home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / mozilla-firefox / include / mork / mdb.h next >
C/C++ Source or Header  |  2006-05-08  |  124KB  |  2,544 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-  */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is mozilla.org code.
  16.  *
  17.  * The Initial Developer of the Original Code is
  18.  * Netscape Communications Corporation.
  19.  * Portions created by the Initial Developer are Copyright (C) 1999
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *   Blake Ross (blake@blakeross.com)
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either of the GNU General Public License Version 2 or later (the "GPL"),
  27.  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the MPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the MPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. #ifndef _MDB_
  40. #define _MDB_ 1
  41.  
  42. #include "nscore.h"
  43. #include "nsISupports.h"
  44. //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
  45.  
  46. // { %%%%% begin scalar typedefs %%%%%
  47. typedef unsigned char  mdb_u1;  // make sure this is one byte
  48. typedef unsigned short mdb_u2;  // make sure this is two bytes
  49. typedef short          mdb_i2;  // make sure this is two bytes
  50. typedef PRUint32       mdb_u4;  // make sure this is four bytes
  51. typedef PRInt32        mdb_i4;  // make sure this is four bytes
  52. typedef PRWord         mdb_ip;  // make sure sizeof(mdb_ip) == sizeof(void*)
  53.  
  54. typedef mdb_u1 mdb_bool;  // unsigned byte with zero=false, nonzero=true
  55.  
  56. /* canonical boolean constants provided only for code clarity: */
  57. #define mdbBool_kTrue  ((mdb_bool) 1) /* actually any nonzero means true */
  58. #define mdbBool_kFalse ((mdb_bool) 0) /* only zero means false */
  59.  
  60. typedef mdb_u4 mdb_id;    // unsigned object identity in a scope
  61. typedef mdb_id mdb_rid;          // unsigned row identity inside scope
  62. typedef mdb_id mdb_tid;          // unsigned table identity inside scope
  63. typedef mdb_u4 mdb_token; // unsigned token for atomized string
  64. typedef mdb_token mdb_scope;     // token used to id scope for rows
  65. typedef mdb_token mdb_kind;      // token used to id kind for tables
  66. typedef mdb_token mdb_column;    // token used to id columns for rows
  67. typedef mdb_token mdb_cscode;    // token used to id charset names
  68. typedef mdb_u4 mdb_seed;  // unsigned collection change counter
  69. typedef mdb_u4 mdb_count; // unsigned collection member count
  70. typedef mdb_u4 mdb_size;  // unsigned physical media size
  71. typedef mdb_u4 mdb_fill;  // unsigned logical content size
  72. typedef mdb_u4 mdb_more;  // more available bytes for larger buffer
  73.  
  74. #define mdbId_kNone ((mdb_id) -1) /* never a valid Mork object ID */
  75.  
  76. typedef mdb_u4 mdb_percent; // 0..100, with values >100 same as 100
  77.  
  78. typedef mdb_u1 mdb_priority; // 0..9, for a total of ten different values
  79.  
  80. // temporary substitute for NS_RESULT, for mdb.h standalone compilation:
  81. typedef nsresult mdb_err;   // equivalent to NS_RESULT
  82.  
  83. // sequence position is signed; negative is useful to mean "before first":
  84. typedef mdb_i4 mdb_pos; // signed zero-based ordinal collection position
  85.  
  86. #define mdbPos_kBeforeFirst ((mdb_pos) -1) /* any negative is before zero */
  87.  
  88. // order is also signed, so we can use three states for comparison order:
  89. typedef mdb_i4 mdb_order; // neg:lessthan, zero:equalto, pos:greaterthan 
  90.  
  91. typedef mdb_order (* mdbAny_Order)(const void* inA, const void* inB, 
  92.   const void* inClosure);
  93.  
  94. // } %%%%% end scalar typedefs %%%%%
  95.  
  96. // { %%%%% begin C structs %%%%%
  97.  
  98. #ifndef mdbScopeStringSet_typedef
  99. typedef struct mdbScopeStringSet mdbScopeStringSet;
  100. #define mdbScopeStringSet_typedef 1
  101. #endif
  102.  
  103. /*| mdbScopeStringSet: a set of null-terminated C strings that enumerate some
  104. **| names of row scopes, so that row scopes intended for use by an application
  105. **| can be declared by an app when trying to open or create a database file.
  106. **| (We use strings and not tokens because we cannot know the tokens for any
  107. **| particular db without having first opened the db.)  The goal is to inform
  108. **| a db runtime that scopes not appearing in this list can be given relatively
  109. **| short shrift in runtime representation, with the expectation that other
  110. **| scopes will not actually be used.  However, a db should still be prepared
  111. **| to handle accessing row scopes not in this list, rather than raising errors.
  112. **| But it could be quite expensive to access a row scope not on the list.
  113. **| Note a zero count for the string set means no such string set is being
  114. **| specified, and that a db should handle all row scopes efficiently. 
  115. **| (It does NOT mean an app plans to use no content whatsoever.)
  116. |*/
  117. #ifndef mdbScopeStringSet_struct
  118. #define mdbScopeStringSet_struct 1
  119. struct mdbScopeStringSet { // vector of scopes for use in db opening policy
  120.   // when mScopeStringSet_Count is zero, this means no scope constraints 
  121.   mdb_count     mScopeStringSet_Count;    // number of strings in vector below
  122.   const char**  mScopeStringSet_Strings;  // null-ended ascii scope strings
  123. };
  124. #endif /*mdbScopeStringSet_struct*/
  125.  
  126. #ifndef mdbOpenPolicy_typedef
  127. typedef struct mdbOpenPolicy mdbOpenPolicy;
  128. #define mdbOpenPolicy_typedef 1
  129. #endif
  130.  
  131. #ifndef mdbOpenPolicy_struct
  132. #define mdbOpenPolicy_struct 1
  133. struct mdbOpenPolicy { // policies affecting db usage for ports and stores
  134.   mdbScopeStringSet  mOpenPolicy_ScopePlan; // predeclare scope usage plan
  135.   mdb_bool           mOpenPolicy_MaxLazy;   // nonzero: do least work
  136.   mdb_bool           mOpenPolicy_MinMemory; // nonzero: use least memory
  137. };
  138. #endif /*mdbOpenPolicy_struct*/
  139.  
  140. #ifndef mdbTokenSet_typedef
  141. typedef struct mdbTokenSet mdbTokenSet;
  142. #define mdbTokenSet_typedef 1
  143. #endif
  144.  
  145. #ifndef mdbTokenSet_struct
  146. #define mdbTokenSet_struct 1
  147. struct mdbTokenSet { // array for a set of tokens, and actual slots used
  148.   mdb_count   mTokenSet_Count;   // number of token slots in the array
  149.   mdb_fill    mTokenSet_Fill;    // the subset of count slots actually used
  150.   mdb_more    mTokenSet_More;    // more tokens available for bigger array
  151.   mdb_token*  mTokenSet_Tokens;  // array of count mdb_token instances
  152. };
  153. #endif /*mdbTokenSet_struct*/
  154.  
  155. #ifndef mdbUsagePolicy_typedef
  156. typedef struct mdbUsagePolicy mdbUsagePolicy;
  157. #define mdbUsagePolicy_typedef 1
  158. #endif
  159.  
  160. /*| mdbUsagePolicy: another version of mdbOpenPolicy which uses tokens instead
  161. **| of scope strings, because usage policies can be constructed for use with a
  162. **| db that is already open, while an open policy must be constructed before a
  163. **| db has yet been opened.
  164. |*/
  165. #ifndef mdbUsagePolicy_struct
  166. #define mdbUsagePolicy_struct 1
  167. struct mdbUsagePolicy { // policies affecting db usage for ports and stores
  168.   mdbTokenSet  mUsagePolicy_ScopePlan; // current scope usage plan
  169.   mdb_bool     mUsagePolicy_MaxLazy;   // nonzero: do least work
  170.   mdb_bool     mUsagePolicy_MinMemory; // nonzero: use least memory
  171. };
  172. #endif /*mdbUsagePolicy_struct*/
  173.  
  174. #ifndef mdbOid_typedef
  175. typedef struct mdbOid mdbOid;
  176. #define mdbOid_typedef 1
  177. #endif
  178.  
  179. #ifndef mdbOid_struct
  180. #define mdbOid_struct 1
  181. struct mdbOid { // identity of some row or table inside a database
  182.   mdb_scope   mOid_Scope;  // scope token for an id's namespace
  183.   mdb_id      mOid_Id;     // identity of object inside scope namespace
  184. };
  185. #endif /*mdbOid_struct*/
  186.  
  187. #ifndef mdbRange_typedef
  188. typedef struct mdbRange mdbRange;
  189. #define mdbRange_typedef 1
  190. #endif
  191.  
  192. #ifndef mdbRange_struct
  193. #define mdbRange_struct 1
  194. struct mdbRange { // range of row positions in a table
  195.   mdb_pos   mRange_FirstPos;  // position of first row
  196.   mdb_pos   mRange_LastPos;   // position of last row
  197. };
  198. #endif /*mdbRange_struct*/
  199.  
  200. #ifndef mdbColumnSet_typedef
  201. typedef struct mdbColumnSet mdbColumnSet;
  202. #define mdbColumnSet_typedef 1
  203. #endif
  204.  
  205. #ifndef mdbColumnSet_struct
  206. #define mdbColumnSet_struct 1
  207. struct mdbColumnSet { // array of column tokens (just the same as mdbTokenSet)
  208.   mdb_count    mColumnSet_Count;    // number of columns
  209.   mdb_column*  mColumnSet_Columns;  // count mdb_column instances
  210. };
  211. #endif /*mdbColumnSet_struct*/
  212.  
  213. #ifndef mdbYarn_typedef
  214. typedef struct mdbYarn mdbYarn;
  215. #define mdbYarn_typedef 1
  216. #endif
  217.  
  218. #ifdef MDB_BEGIN_C_LINKAGE_define
  219. #define MDB_BEGIN_C_LINKAGE_define 1
  220. #define MDB_BEGIN_C_LINKAGE extern "C" {
  221. #define MDB_END_C_LINKAGE }
  222. #endif /*MDB_BEGIN_C_LINKAGE_define*/
  223.  
  224. /*| mdbYarn_mGrow: an abstract API for growing the size of a mdbYarn
  225. **| instance.  With respect to a specific API that requires a caller
  226. **| to supply a string (mdbYarn) that a callee fills with content
  227. **| that might exceed the specified size, mdbYarn_mGrow is a caller-
  228. **| supplied means of letting a callee attempt to increase the string
  229. **| size to become large enough to receive all content available.
  230. **|
  231. **|| Grow(): a method for requesting that a yarn instance be made
  232. **| larger in size.  Note that such requests need not be honored, and
  233. **| need not be honored in full if only partial size growth is desired.
  234. **| (Note that no nsIMdbEnv instance is passed as argument, although one
  235. **| might be needed in some circumstances.  So if an nsIMdbEnv is needed,
  236. **| a reference to one might be held inside a mdbYarn member slot.)
  237. **|
  238. **|| self: a yarn instance to be grown.  Presumably this yarn is
  239. **| the instance which holds the mYarn_Grow method pointer.  Yarn
  240. **| instancesshould only be passed to grow methods which they were
  241. **| specifically designed to fit, as indicated by the mYarn_Grow slot.
  242. **|
  243. **|| inNewSize: the new desired value for slot mYarn_Size in self.
  244. **| If mYarn_Size is already this big, then nothing should be done.
  245. **| If inNewSize is larger than seems feasible or desirable to honor,
  246. **| then any size restriction policy can be used to grow to some size
  247. **| greater than mYarn_Size.  (Grow() might even grow to a size
  248. **| greater than inNewSize in order to make the increase in size seem
  249. **| worthwhile, rather than growing in many smaller steps over time.)
  250. |*/
  251. typedef void (* mdbYarn_mGrow)(mdbYarn* self, mdb_size inNewSize);
  252. // mdbYarn_mGrow methods must be declared with C linkage in C++
  253.  
  254. /*| mdbYarn: a variable length "string" of arbitrary binary bytes,
  255. **| whose length is mYarn_Fill, inside a buffer mYarn_Buf that has
  256. **| at most mYarn_Size byte of physical space.
  257. **|
  258. **|| mYarn_Buf: a pointer to space containing content.  This slot
  259. **| might never be nil when mYarn_Size is nonzero, but checks for nil
  260. **| are recommended anyway.
  261. **| (Implementations of mdbYarn_mGrow methods should take care to
  262. **| ensure the existence of a replacement before dropping old Bufs.)
  263. **| Content in Buf can be anything in any format, but the mYarn_Form
  264. **| implies the actual format by some caller-to-callee convention.
  265. **| mYarn_Form==0 implies US-ASCII iso-8859-1 Latin1 string content.
  266. **|
  267. **|| mYarn_Size: the physical size of Buf in bytes.  Note that if one
  268. **| intends to terminate a string with a null byte, that it must not
  269. **| be written at or after mYarn_Buf[mYarn_Size] because this is after
  270. **| the last byte in the physical buffer space.  Size can be zero,
  271. **| which means the string has no content whatsoever; note that when
  272. **| Size is zero, this is a suitable reason for Buf==nil as well.
  273. **|
  274. **|| mYarn_Fill: the logical content in Buf in bytes, where Fill must
  275. **| never exceed mYarn_Size.  Note that yarn strings might not have a
  276. **| terminating null byte (since they might not even be C strings), but
  277. **| when they do, such terminating nulls are considered part of content
  278. **| and therefore Fill will count such null bytes.  So an "empty" C
  279. **| string will have Fill==1, because content includes one null byte.
  280. **| Fill does not mean "length" when applied to C strings for this
  281. **| reason.  However, clients using yarns to hold C strings can infer
  282. **| that length is equal to Fill-1 (but should take care to handle the
  283. **| case where Fill==0).  To be paranoid, one can always copy to a
  284. **| destination with size exceeding Fill, and place a redundant null
  285. **| byte in the Fill position when this simplifies matters.
  286. **|
  287. **|| mYarn_Form: a designation of content format within mYarn_Buf.
  288. **| The semantics of this slot are the least well defined, since the
  289. **| actual meaning is context dependent, to the extent that callers
  290. **| and callees must agree on format encoding conventions when such
  291. **| are not standardized in many computing contexts.  However, in the
  292. **| context of a specific mdb database, mYarn_Form is a token for an
  293. **| atomized string in that database that typically names a preferred
  294. **| mime type charset designation.  If and when mdbYarn is used for
  295. **| other purposes away from the mdb interface, folks can use another
  296. **| convention system for encoding content formats.  However, in all
  297. **| contexts is it useful to maintain the convention that Form==0
  298. **| implies Buf contains US-ASCII iso-8859-1 Latin1 string content.
  299. **|
  300. **|| mYarn_Grow: either a mdbYarn_mGrow method, or else nil.  When
  301. **| a mdbYarn_mGrow method is provided, this method can be used to
  302. **| request a yarn buf size increase.  A caller who constructs the 
  303. **| original mdbYarn instance decides whether a grow method is necessary
  304. **| or desirable, and uses only grow methods suitable for the buffering
  305. **| nature of a specific mdbYarn instance.  (For example, Buf might be a
  306. **| staticly allocated string space which switches to something heap-based
  307. **| when grown, and subsequent calls to grow the yarn must distinguish the
  308. **| original static string from heap allocated space, etc.) Note that the
  309. **| method stored in mYarn_Grow can change, and this might be a common way
  310. **| to track memory managent changes in policy for mYarn_Buf.
  311. |*/
  312. #ifndef mdbYarn_struct
  313. #define mdbYarn_struct 1
  314. struct mdbYarn { // buffer with caller space allocation semantics
  315.   void*         mYarn_Buf;   // space for holding any binary content
  316.   mdb_fill      mYarn_Fill;  // logical content in Buf in bytes
  317.   mdb_size      mYarn_Size;  // physical size of Buf in bytes
  318.   mdb_more      mYarn_More;  // more available bytes if Buf is bigger
  319.   mdb_cscode    mYarn_Form;  // charset format encoding
  320.   mdbYarn_mGrow mYarn_Grow;  // optional method to grow mYarn_Buf
  321.   
  322.   // Subclasses might add further slots after mYarn_Grow in order to
  323.   // maintain bookkeeping needs, such as state info about mYarn_Buf.
  324. };
  325. #endif /*mdbYarn_struct*/
  326.  
  327. // } %%%%% end C structs %%%%%
  328.  
  329. // { %%%%% begin class forward defines %%%%%
  330. class nsIMdbEnv;
  331. class nsIMdbObject;
  332. class nsIMdbErrorHook;
  333. class nsIMdbCompare;
  334. class nsIMdbThumb;
  335. class nsIMdbFactory;
  336. class nsIMdbFile;
  337. class nsIMdbPort;
  338. class nsIMdbStore;
  339. class nsIMdbCursor;
  340. class nsIMdbPortTableCursor;
  341. class nsIMdbCollection;
  342. class nsIMdbTable;
  343. class nsIMdbTableRowCursor;
  344. class nsIMdbRow;
  345. class nsIMdbRowCellCursor;
  346. class nsIMdbBlob;
  347. class nsIMdbCell;
  348. class nsIMdbSorting;
  349. // } %%%%% end class forward defines %%%%%
  350.  
  351.  
  352. // { %%%%% begin C++ abstract class interfaces %%%%%
  353.  
  354. /*| nsIMdbObject: base class for all message db class interfaces
  355. **|
  356. **|| factory: all nsIMdbObjects from the same code suite have the same factory
  357. **|
  358. **|| refcounting: both strong and weak references, to ensure strong refs are
  359. **| acyclic, while weak refs can cause cycles.  CloseMdbObject() is
  360. **| called when (strong) use counts hit zero, but clients can call this close
  361. **| method early for some reason, if absolutely necessary even though it will
  362. **| thwart the other uses of the same object.  Note that implementations must
  363. **| cope with close methods being called arbitrary numbers of times.  The COM
  364. **| calls to AddRef() and release ref map directly to strong use ref calls,
  365. **| but the total ref count for COM objects is the sum of weak & strong refs.
  366. |*/
  367.  
  368. #define NS_IMDBOBJECT_IID_STR "5533ea4b-14c3-4bef-ac60-22f9e9a49084"
  369.  
  370. #define NS_IMDBOBJECT_IID \
  371. {0x5533ea4b, 0x14c3, 0x4bef, \
  372. { 0xac, 0x60, 0x22, 0xf9, 0xe9, 0xa4, 0x90, 0x84}}
  373.  
  374. class nsIMdbObject : public nsISupports { // msg db base class
  375. public:
  376.  
  377.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBOBJECT_IID)
  378. // { ===== begin nsIMdbObject methods =====
  379.  
  380.   // { ----- begin attribute methods -----
  381.   NS_IMETHOD IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly) = 0;
  382.   // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
  383.   // } ----- end attribute methods -----
  384.  
  385.   // { ----- begin factory methods -----
  386.   NS_IMETHOD GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory) = 0; 
  387.   // } ----- end factory methods -----
  388.  
  389.   // { ----- begin ref counting for well-behaved cyclic graphs -----
  390.   NS_IMETHOD GetWeakRefCount(nsIMdbEnv* ev, // weak refs
  391.     mdb_count* outCount) = 0;  
  392.   NS_IMETHOD GetStrongRefCount(nsIMdbEnv* ev, // strong refs
  393.     mdb_count* outCount) = 0;
  394.  
  395.   NS_IMETHOD AddWeakRef(nsIMdbEnv* ev) = 0;
  396.   NS_IMETHOD AddStrongRef(nsIMdbEnv* ev) = 0;
  397.  
  398.   NS_IMETHOD CutWeakRef(nsIMdbEnv* ev) = 0;
  399.   NS_IMETHOD CutStrongRef(nsIMdbEnv* ev) = 0;
  400.   
  401.   NS_IMETHOD CloseMdbObject(nsIMdbEnv* ev) = 0; // called at strong refs zero
  402.   NS_IMETHOD IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen) = 0;
  403.   // } ----- end ref counting -----
  404.   
  405. // } ===== end nsIMdbObject methods =====
  406. };
  407.  
  408. /*| nsIMdbErrorHook: a base class for clients of this API to subclass, in order
  409. **| to provide a callback installable in nsIMdbEnv for error notifications. If
  410. **| apps that subclass nsIMdbErrorHook wish to maintain a reference to the env
  411. **| that contains the hook, then this should be a weak ref to avoid cycles.
  412. **|
  413. **|| OnError: when nsIMdbEnv has an error condition that causes the total count
  414. **| of errors to increase, then nsIMdbEnv should call OnError() to report the
  415. **| error in some fashion when an instance of nsIMdbErrorHook is installed.  The
  416. **| variety of string flavors is currently due to the uncertainty here in the
  417. **| nsIMdbBlob and nsIMdbCell interfaces.  (Note that overloading by using the
  418. **| same method name is not necessary here, and potentially less clear.)
  419. |*/
  420. class nsIMdbErrorHook : public nsISupports{ // env callback handler to report errors
  421. public:
  422.  
  423. // { ===== begin error methods =====
  424.   NS_IMETHOD OnErrorString(nsIMdbEnv* ev, const char* inAscii) = 0;
  425.   NS_IMETHOD OnErrorYarn(nsIMdbEnv* ev, const mdbYarn* inYarn) = 0;
  426. // } ===== end error methods =====
  427.  
  428. // { ===== begin warning methods =====
  429.   NS_IMETHOD OnWarningString(nsIMdbEnv* ev, const char* inAscii) = 0;
  430.   NS_IMETHOD OnWarningYarn(nsIMdbEnv* ev, const mdbYarn* inYarn) = 0;
  431. // } ===== end warning methods =====
  432.  
  433. // { ===== begin abort hint methods =====
  434.   NS_IMETHOD OnAbortHintString(nsIMdbEnv* ev, const char* inAscii) = 0;
  435.   NS_IMETHOD OnAbortHintYarn(nsIMdbEnv* ev, const mdbYarn* inYarn) = 0;
  436. // } ===== end abort hint methods =====
  437. };
  438.  
  439. /*| nsIMdbCompare: a caller-supplied yarn comparison interface.  When two yarns
  440. **| are compared to each other with Order(), this method should return a signed
  441. **| long integer denoting relation R between the 1st and 2nd yarn instances
  442. **| such that (First R Second), where negative is less than, zero is equal to,
  443. **| and positive is greater than.  Note that both yarns are readonly, and the
  444. **| Order() method should make no attempt to modify the yarn content.
  445. |*/
  446. class nsIMdbCompare { // caller-supplied yarn comparison
  447. public:
  448.  
  449. // { ===== begin nsIMdbCompare methods =====
  450.   NS_IMETHOD Order(nsIMdbEnv* ev,      // compare first to second yarn
  451.     const mdbYarn* inFirst,   // first yarn in comparison
  452.     const mdbYarn* inSecond,  // second yarn in comparison
  453.     mdb_order* outOrder) = 0; // negative="<", zero="=", positive=">"
  454.     
  455.   NS_IMETHOD AddStrongRef(nsIMdbEnv* ev) = 0; // does nothing
  456.   NS_IMETHOD CutStrongRef(nsIMdbEnv* ev) = 0; // does nothing
  457. // } ===== end nsIMdbCompare methods =====
  458.   
  459. };
  460.  
  461. /*| nsIMdbHeap: abstract memory allocation interface. 
  462. **|
  463. **|| Alloc: return a block at least inSize bytes in size with alignment
  464. **| suitable for any native type (such as long integers).  When no such
  465. **| block can be allocated, failure is indicated by a null address in
  466. **| addition to reporting an error in the environment.
  467. **|
  468. **|| Free: deallocate a block allocated or resized earlier by the same
  469. **| heap instance.  If the inBlock parameter is nil, the heap should do
  470. **| nothing (and crashing is strongly discouraged).
  471. |*/
  472. class nsIMdbHeap { // caller-supplied memory management interface
  473. public:
  474. // { ===== begin nsIMdbHeap methods =====
  475.   NS_IMETHOD Alloc(nsIMdbEnv* ev, // allocate a piece of memory
  476.     mdb_size inSize,        // requested byte size of new memory block 
  477.     void** outBlock) = 0;   // memory block of inSize bytes, or nil
  478.     
  479.   NS_IMETHOD Free(nsIMdbEnv* ev, // free block from Alloc or Resize()
  480.     void* ioBlock) = 0;     // block to be destroyed/deallocated
  481.     
  482.   NS_IMETHOD HeapAddStrongRef(nsIMdbEnv* ev) = 0;
  483.   NS_IMETHOD HeapCutStrongRef(nsIMdbEnv* ev) = 0;
  484.     
  485. // } ===== end nsIMdbHeap methods =====
  486. };
  487.  
  488. /*| nsIMdbCPlusHeap: Alloc() with global ::new(), Free() with global ::delete(). 
  489. **| Resize() is done by ::new() followed by ::delete().
  490. |*/
  491. class nsIMdbCPlusHeap { // caller-supplied memory management interface
  492. public:
  493. // { ===== begin nsIMdbHeap methods =====
  494.   NS_IMETHOD Alloc(nsIMdbEnv* ev, // allocate a piece of memory
  495.     mdb_size inSize,   // requested size of new memory block 
  496.     void** outBlock);  // memory block of inSize bytes, or nil
  497.     
  498.   NS_IMETHOD Free(nsIMdbEnv* ev, // free block allocated earlier by Alloc()
  499.     void* inBlock);
  500.     
  501.   NS_IMETHOD HeapAddStrongRef(nsIMdbEnv* ev);
  502.   NS_IMETHOD HeapCutStrongRef(nsIMdbEnv* ev);
  503. // } ===== end nsIMdbHeap methods =====
  504. };
  505.  
  506. /*| nsIMdbThumb: 
  507. |*/
  508.  
  509.  
  510. #define NS_IMDBTHUMB_IID_STR "6d3ad7c1-a809-4e74-8577-49fa9a4562fa"
  511.  
  512. #define NS_IMDBTHUMB_IID \
  513. {0x6d3ad7c1, 0xa809, 0x4e74, \
  514. { 0x85, 0x77, 0x49, 0xfa, 0x9a, 0x45, 0x62, 0xfa}}
  515.  
  516.  
  517. class nsIMdbThumb : public nsISupports { // closure for repeating incremental method
  518. public:
  519.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBTHUMB_IID)
  520.  
  521. // { ===== begin nsIMdbThumb methods =====
  522.   NS_IMETHOD GetProgress(nsIMdbEnv* ev,
  523.     mdb_count* outTotal,    // total somethings to do in operation
  524.     mdb_count* outCurrent,  // subportion of total completed so far
  525.     mdb_bool* outDone,      // is operation finished?
  526.     mdb_bool* outBroken     // is operation irreparably dead and broken?
  527.   ) = 0;
  528.   
  529.   NS_IMETHOD DoMore(nsIMdbEnv* ev,
  530.     mdb_count* outTotal,    // total somethings to do in operation
  531.     mdb_count* outCurrent,  // subportion of total completed so far
  532.     mdb_bool* outDone,      // is operation finished?
  533.     mdb_bool* outBroken     // is operation irreparably dead and broken?
  534.   ) = 0;
  535.   
  536.   NS_IMETHOD CancelAndBreakThumb( // cancel pending operation
  537.     nsIMdbEnv* ev) = 0;
  538. // } ===== end nsIMdbThumb methods =====
  539. };
  540.  
  541. /*| nsIMdbEnv: a context parameter used when calling most abstract db methods.
  542. **| The main purpose of such an object is to permit a database implementation
  543. **| to avoid the use of globals to share information between various parts of
  544. **| the implementation behind the abstract db interface.  An environment acts
  545. **| like a session object for a given calling thread, and callers should use
  546. **| at least one different nsIMdbEnv instance for each thread calling the API.
  547. **| While the database implementation might not be threaded, it is highly
  548. **| desirable that the db be thread-safe if calling threads use distinct
  549. **| instances of nsIMdbEnv.  Callers can stop at one nsIMdbEnv per thread, or they
  550. **| might decide to make on nsIMdbEnv instance for every nsIMdbPort opened, so that
  551. **| error information is segregated by database instance.  Callers create
  552. **| instances of nsIMdbEnv by calling the MakeEnv() method in nsIMdbFactory. 
  553. **|
  554. **|| tracing: an environment might support some kind of tracing, and this
  555. **| boolean attribute permits such activity to be enabled or disabled.
  556. **|
  557. **|| errors: when a call to the abstract db interface returns, a caller might
  558. **| check the number of outstanding errors to see whether the operation did
  559. **| actually succeed. Each nsIMdbEnv should have all its errors cleared by a
  560. **| call to ClearErrors() before making each call to the abstract db API,
  561. **| because outstanding errors might disable further database actions.  (This
  562. **| is not done inside the db interface, because the db cannot in general know
  563. **| when a call originates from inside or outside -- only the app knows this.)
  564. **|
  565. **|| error hook: callers can install an instance of nsIMdbErrorHook to receive
  566. **| error notifications whenever the error count increases.  The hook can
  567. **| be uninstalled by passing a null pointer.
  568. **|
  569. |*/
  570.  
  571. #define NS_IMDBENV_IID_STR "a765e46b-efb6-41e6-b75b-c5d6bd710594"
  572.  
  573. #define NS_IMDBENV_IID \
  574. {0xa765e46b, 0xefb6, 0x41e6, \
  575. { 0xb7, 0x5b, 0xc5, 0xd6, 0xbd, 0x71, 0x05, 0x94}}
  576.  
  577. class nsIMdbEnv : public nsISupports { // db specific context parameter
  578. public:
  579.  
  580.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBENV_IID)
  581. // { ===== begin nsIMdbEnv methods =====
  582.  
  583.   // { ----- begin attribute methods -----
  584.   NS_IMETHOD GetErrorCount(mdb_count* outCount,
  585.     mdb_bool* outShouldAbort) = 0;
  586.   NS_IMETHOD GetWarningCount(mdb_count* outCount,
  587.     mdb_bool* outShouldAbort) = 0;
  588.   
  589.   NS_IMETHOD GetEnvBeVerbose(mdb_bool* outBeVerbose) = 0;
  590.   NS_IMETHOD SetEnvBeVerbose(mdb_bool inBeVerbose) = 0;
  591.   
  592.   NS_IMETHOD GetDoTrace(mdb_bool* outDoTrace) = 0;
  593.   NS_IMETHOD SetDoTrace(mdb_bool inDoTrace) = 0;
  594.   
  595.   NS_IMETHOD GetAutoClear(mdb_bool* outAutoClear) = 0;
  596.   NS_IMETHOD SetAutoClear(mdb_bool inAutoClear) = 0;
  597.   
  598.   NS_IMETHOD GetErrorHook(nsIMdbErrorHook** acqErrorHook) = 0;
  599.   NS_IMETHOD SetErrorHook(
  600.     nsIMdbErrorHook* ioErrorHook) = 0; // becomes referenced
  601.   
  602.   NS_IMETHOD GetHeap(nsIMdbHeap** acqHeap) = 0;
  603.   NS_IMETHOD SetHeap(
  604.     nsIMdbHeap* ioHeap) = 0; // becomes referenced
  605.   // } ----- end attribute methods -----
  606.   
  607.   NS_IMETHOD ClearErrors() = 0; // clear errors beore re-entering db API
  608.   NS_IMETHOD ClearWarnings() = 0; // clear warnings
  609.   NS_IMETHOD ClearErrorsAndWarnings() = 0; // clear both errors & warnings
  610. // } ===== end nsIMdbEnv methods =====
  611. };
  612.  
  613. /*| nsIMdbFactory: the main entry points to the abstract db interface.  A DLL
  614. **| that supports this mdb interface need only have a single exported method
  615. **| that will return an instance of nsIMdbFactory, so that further methods in
  616. **| the suite can be accessed from objects returned by nsIMdbFactory methods.
  617. **|
  618. **|| mdbYarn: note all nsIMdbFactory subclasses must guarantee null
  619. **| termination of all strings written into mdbYarn instances, as long as
  620. **| mYarn_Size and mYarn_Buf are nonzero.  Even truncated string values must
  621. **| be null terminated.  This is more strict behavior than mdbYarn requires,
  622. **| but it is part of the nsIMdbFactory interface.
  623. **|
  624. **|| envs: an environment instance is required as per-thread context for
  625. **| most of the db method calls, so nsIMdbFactory creates such instances.
  626. **|
  627. **|| rows: callers must be able to create row instances that are independent
  628. **| of storage space that is part of the db content graph.  Many interfaces
  629. **| for data exchange have strictly copy semantics, so that a row instance
  630. **| has no specific identity inside the db content model, and the text in
  631. **| cells are an independenty copy of unexposed content inside the db model.
  632. **| Callers are expected to maintain one or more row instances as a buffer
  633. **| for staging cell content copied into or out of a table inside the db.
  634. **| Callers are urged to use an instance of nsIMdbRow created by the nsIMdbFactory
  635. **| code suite, because reading and writing might be much more efficient than
  636. **| when using a hand-rolled nsIMdbRow subclass with no relation to the suite.
  637. **|
  638. **|| ports: a port is a readonly interface to a specific database file. Most
  639. **| of the methods to access a db file are suitable for a readonly interface,
  640. **| so a port is the basic minimum for accessing content.  This makes it
  641. **| possible to read other external formats for import purposes, without
  642. **| needing the code or competence necessary to write every such format.  So
  643. **| we can write generic import code just once, as long as every format can
  644. **| show a face based on nsIMdbPort. (However, same suite import can be faster.)
  645. **| Given a file name and the first 512 bytes of a file, a factory can say if
  646. **| a port can be opened by this factory.  Presumably an app maintains chains
  647. **| of factories for different suites, and asks each in turn about opening a
  648. **| a prospective file for reading (as a port) or writing (as a store).  I'm
  649. **| not ready to tackle issues of format fidelity and factory chain ordering.
  650. **|
  651. **|| stores: a store is a mutable interface to a specific database file, and
  652. **| includes the port interface plus any methods particular to writing, which
  653. **| are few in number.  Presumably the set of files that can be opened as
  654. **| stores is a subset of the set of files that can be opened as ports.  A
  655. **| new store can be created with CreateNewFileStore() by supplying a new
  656. **| file name which does not yet exist (callers are always responsible for
  657. **| destroying any existing files before calling this method). 
  658. |*/
  659.  
  660. #define NS_IMDBFACTORY_IID_STR "2b80395c-b91e-4990-b1a7-023e99ab14e9"
  661.  
  662. #define NS_IMDBFACTORY_IID \
  663. {0xf04aa4ab, 0x1fe, 0x4115, \
  664. { 0xa4, 0xa5, 0x68, 0x19, 0xdf, 0xf1, 0x10, 0x3d}}
  665.  
  666.  
  667. class nsIMdbFactory : public nsISupports { // suite entry points
  668. public:
  669.  
  670.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBFACTORY_IID)
  671. // { ===== begin nsIMdbFactory methods =====
  672.  
  673.   // { ----- begin file methods -----
  674.   NS_IMETHOD OpenOldFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
  675.     const char* inFilePath,
  676.     mdb_bool inFrozen, nsIMdbFile** acqFile) = 0;
  677.   // Choose some subclass of nsIMdbFile to instantiate, in order to read
  678.   // (and write if not frozen) the file known by inFilePath.  The file
  679.   // returned should be open and ready for use, and presumably positioned
  680.   // at the first byte position of the file.  The exact manner in which
  681.   // files must be opened is considered a subclass specific detail, and
  682.   // other portions or Mork source code don't want to know how it's done.
  683.  
  684.   NS_IMETHOD CreateNewFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
  685.     const char* inFilePath,
  686.     nsIMdbFile** acqFile) = 0;
  687.   // Choose some subclass of nsIMdbFile to instantiate, in order to read
  688.   // (and write if not frozen) the file known by inFilePath.  The file
  689.   // returned should be created and ready for use, and presumably positioned
  690.   // at the first byte position of the file.  The exact manner in which
  691.   // files must be opened is considered a subclass specific detail, and
  692.   // other portions or Mork source code don't want to know how it's done.
  693.   // } ----- end file methods -----
  694.  
  695.   // { ----- begin env methods -----
  696.   NS_IMETHOD MakeEnv(nsIMdbHeap* ioHeap, nsIMdbEnv** acqEnv) = 0; // acquire new env
  697.   // ioHeap can be nil, causing a MakeHeap() style heap instance to be used
  698.   // } ----- end env methods -----
  699.  
  700.   // { ----- begin heap methods -----
  701.   NS_IMETHOD MakeHeap(nsIMdbEnv* ev, nsIMdbHeap** acqHeap) = 0; // acquire new heap
  702.   // } ----- end heap methods -----
  703.  
  704.   // { ----- begin compare methods -----
  705.   NS_IMETHOD MakeCompare(nsIMdbEnv* ev, nsIMdbCompare** acqCompare) = 0; // ASCII
  706.   // } ----- end compare methods -----
  707.  
  708.   // { ----- begin row methods -----
  709.   NS_IMETHOD MakeRow(nsIMdbEnv* ev, nsIMdbHeap* ioHeap, nsIMdbRow** acqRow) = 0; // new row
  710.   // ioHeap can be nil, causing the heap associated with ev to be used
  711.   // } ----- end row methods -----
  712.   
  713.   // { ----- begin port methods -----
  714.   NS_IMETHOD CanOpenFilePort(
  715.     nsIMdbEnv* ev, // context
  716.     // const char* inFilePath, // the file to investigate
  717.     // const mdbYarn* inFirst512Bytes,
  718.     nsIMdbFile* ioFile, // db abstract file interface
  719.     mdb_bool* outCanOpen, // whether OpenFilePort() might succeed
  720.     mdbYarn* outFormatVersion) = 0; // informal file format description
  721.     
  722.   NS_IMETHOD OpenFilePort(
  723.     nsIMdbEnv* ev, // context
  724.     nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
  725.     // const char* inFilePath, // the file to open for readonly import
  726.     nsIMdbFile* ioFile, // db abstract file interface
  727.     const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
  728.     nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental port open
  729.   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  730.   // then call nsIMdbFactory::ThumbToOpenPort() to get the port instance.
  731.  
  732.   NS_IMETHOD ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort()
  733.     nsIMdbEnv* ev, // context
  734.     nsIMdbThumb* ioThumb, // thumb from OpenFilePort() with done status
  735.     nsIMdbPort** acqPort) = 0; // acquire new port object
  736.   // } ----- end port methods -----
  737.   
  738.   // { ----- begin store methods -----
  739.   NS_IMETHOD CanOpenFileStore(
  740.     nsIMdbEnv* ev, // context
  741.     // const char* inFilePath, // the file to investigate
  742.     // const mdbYarn* inFirst512Bytes,
  743.     nsIMdbFile* ioFile, // db abstract file interface
  744.     mdb_bool* outCanOpenAsStore, // whether OpenFileStore() might succeed
  745.     mdb_bool* outCanOpenAsPort, // whether OpenFilePort() might succeed
  746.     mdbYarn* outFormatVersion) = 0; // informal file format description
  747.     
  748.   NS_IMETHOD OpenFileStore( // open an existing database
  749.     nsIMdbEnv* ev, // context
  750.     nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
  751.     // const char* inFilePath, // the file to open for general db usage
  752.     nsIMdbFile* ioFile, // db abstract file interface
  753.     const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
  754.     nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental store open
  755.   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  756.   // then call nsIMdbFactory::ThumbToOpenStore() to get the store instance.
  757.     
  758.   NS_IMETHOD
  759.   ThumbToOpenStore( // redeem completed thumb from OpenFileStore()
  760.     nsIMdbEnv* ev, // context
  761.     nsIMdbThumb* ioThumb, // thumb from OpenFileStore() with done status
  762.     nsIMdbStore** acqStore) = 0; // acquire new db store object
  763.   
  764.   NS_IMETHOD CreateNewFileStore( // create a new db with minimal content
  765.     nsIMdbEnv* ev, // context
  766.     nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
  767.     // const char* inFilePath, // name of file which should not yet exist
  768.     nsIMdbFile* ioFile, // db abstract file interface
  769.     const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
  770.     nsIMdbStore** acqStore) = 0; // acquire new db store object
  771.   // } ----- end store methods -----
  772.  
  773. // } ===== end nsIMdbFactory methods =====
  774. };
  775.  
  776. extern "C" nsIMdbFactory* MakeMdbFactory(); 
  777.  
  778. /*| nsIMdbFile: abstract file interface resembling the original morkFile
  779. **| abstract interface (which was in turn modeled on the file interface
  780. **| from public domain IronDoc).  The design of this file interface is
  781. **| complicated by the fact that some DB's will not find this interface
  782. **| adequate for all runtime requirements (even though this file API is
  783. **| enough to implement text-based DB's like Mork).  For this reason,
  784. **| more methods have been added to let a DB library force the file to
  785. **| become closed so the DB can reopen the file in some other manner.
  786. **| Folks are encouraged to suggest ways to tune this interface to suit
  787. **| DB's that cannot manage to pull their maneuvers even given this API.
  788. **|
  789. **|| Tell: get the current i/o position in file
  790. **|
  791. **|| Seek: change the current i/o position in file
  792. **|
  793. **|| Eof: return file's total length in bytes
  794. **|
  795. **|| Read: input inSize bytes into outBuf, returning actual transfer size
  796. **|
  797. **|| Get: read starting at specific file offset (e.g. Seek(); Read();)
  798. **|
  799. **|| Write: output inSize bytes from inBuf, returning actual transfer size
  800. **|
  801. **|| Put: write starting at specific file offset (e.g. Seek(); Write();)
  802. **|
  803. **|| Flush: if written bytes are buffered, push them to final destination
  804. **|
  805. **|| Path: get file path in some string representation.  This is intended
  806. **| either to support the display of file name in a user presentation, or
  807. **| to support the closing and reopening of the file when the DB needs more
  808. **| exotic file access than is presented by the nsIMdbFile interface.
  809. **|
  810. **|| Steal: tell this file to close any associated i/o stream in the file
  811. **| system, because the file ioThief intends to reopen the file in order
  812. **| to provide the MDB implementation with more exotic file access than is
  813. **| offered by the nsIMdbFile alone.  Presumably the thief knows enough
  814. **| from Path() in order to know which file to reopen.  If Steal() is
  815. **| successful, this file should probably delegate all future calls to
  816. **| the nsIMdbFile interface down to the thief files, so that even after
  817. **| the file has been stolen, it can still be read, written, or forcibly
  818. **| closed (by a call to CloseMdbObject()).
  819. **|
  820. **|| Thief: acquire and return thief passed to an earlier call to Steal().
  821. |*/
  822.  
  823. #define NS_IMDBFILE_IID_STR "f04aa4ab-1fe7-4115-a4a5-6819dff1103d"
  824.  
  825. #define NS_IMDBFILE_IID \
  826. {0xf04aa4ab, 0x1fe, 0x4115, \
  827. { 0xa4, 0xa5, 0x68, 0x19, 0xdf, 0xf1, 0x10, 0x3d}}
  828.  
  829. class nsIMdbFile : public nsISupports { // minimal file interface
  830. public:
  831.  
  832.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBFILE_IID)
  833. // { ===== begin nsIMdbFile methods =====
  834.  
  835.   // { ----- begin pos methods -----
  836.   NS_IMETHOD Tell(nsIMdbEnv* ev, mdb_pos* outPos) const = 0;
  837.   NS_IMETHOD Seek(nsIMdbEnv* ev, mdb_pos inPos, mdb_pos *outPos) = 0;
  838.   NS_IMETHOD Eof(nsIMdbEnv* ev, mdb_pos* outPos) = 0;
  839.   // } ----- end pos methods -----
  840.  
  841.   // { ----- begin read methods -----
  842.   NS_IMETHOD Read(nsIMdbEnv* ev, void* outBuf, mdb_size inSize,
  843.     mdb_size* outActualSize) = 0;
  844.   NS_IMETHOD Get(nsIMdbEnv* ev, void* outBuf, mdb_size inSize,
  845.     mdb_pos inPos, mdb_size* outActualSize) = 0;
  846.   // } ----- end read methods -----
  847.     
  848.   // { ----- begin write methods -----
  849.   NS_IMETHOD  Write(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize,
  850.     mdb_size* outActualSize) = 0;
  851.   NS_IMETHOD  Put(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize,
  852.     mdb_pos inPos, mdb_size* outActualSize) = 0;
  853.   NS_IMETHOD  Flush(nsIMdbEnv* ev) = 0;
  854.   // } ----- end attribute methods -----
  855.     
  856.   // { ----- begin path methods -----
  857.   NS_IMETHOD  Path(nsIMdbEnv* ev, mdbYarn* outFilePath) = 0;
  858.   // } ----- end path methods -----
  859.     
  860.   // { ----- begin replacement methods -----
  861.   NS_IMETHOD  Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief) = 0;
  862.   NS_IMETHOD  Thief(nsIMdbEnv* ev, nsIMdbFile** acqThief) = 0;
  863.   // } ----- end replacement methods -----
  864.  
  865.   // { ----- begin versioning methods -----
  866.   NS_IMETHOD BecomeTrunk(nsIMdbEnv* ev) = 0;
  867.   // If this file is a file version branch created by calling AcquireBud(),
  868.   // BecomeTrunk() causes this file's content to replace the original
  869.   // file's content, typically by assuming the original file's identity.
  870.   // This default implementation of BecomeTrunk() does nothing, and this
  871.   // is appropriate behavior for files which are not branches, and is
  872.   // also the right behavior for files returned from AcquireBud() which are
  873.   // in fact the original file that has been truncated down to zero length.
  874.  
  875.   NS_IMETHOD AcquireBud(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
  876.     nsIMdbFile** acqBud) = 0; // acquired file for new version of content
  877.   // AcquireBud() starts a new "branch" version of the file, empty of content,
  878.   // so that a new version of the file can be written.  This new file
  879.   // can later be told to BecomeTrunk() the original file, so the branch
  880.   // created by budding the file will replace the original file.  Some
  881.   // file subclasses might initially take the unsafe but expedient
  882.   // approach of simply truncating this file down to zero length, and
  883.   // then returning the same morkFile pointer as this, with an extra
  884.   // reference count increment.  Note that the caller of AcquireBud() is
  885.   // expected to eventually call CutStrongRef() on the returned file
  886.   // in order to release the strong reference.  High quality versions
  887.   // of morkFile subclasses will create entirely new files which later
  888.   // are renamed to become the old file, so that better transactional
  889.   // behavior is exhibited by the file, so crashes protect old files.
  890.   // Note that AcquireBud() is an illegal operation on readonly files.
  891.   // } ----- end versioning methods -----
  892.  
  893. // } ===== end nsIMdbFile methods =====
  894. };
  895.  
  896. /*| nsIMdbPort: a readonly interface to a specific database file. The mutable
  897. **| nsIMdbStore interface is a subclass that includes writing behavior, but
  898. **| most of the needed db methods appear in the readonly nsIMdbPort interface.
  899. **|
  900. **|| mdbYarn: note all nsIMdbPort and nsIMdbStore subclasses must guarantee null
  901. **| termination of all strings written into mdbYarn instances, as long as
  902. **| mYarn_Size and mYarn_Buf are nonzero.  Even truncated string values must
  903. **| be null terminated.  This is more strict behavior than mdbYarn requires,
  904. **| but it is part of the nsIMdbPort and nsIMdbStore interface.
  905. **|
  906. **|| attributes: methods are provided to distinguish a readonly port from a
  907. **| mutable store, and whether a mutable store actually has any dirty content.
  908. **|
  909. **|| filepath: the file path used to open the port from the nsIMdbFactory can be
  910. **| queried and discovered by GetPortFilePath(), which includes format info.
  911. **|
  912. **|| export: a port can write itself in other formats, with perhaps a typical
  913. **| emphasis on text interchange formats used by other systems.  A port can be
  914. **| queried to determine its preferred export interchange format, and a port
  915. **| can be queried to see whether a specific export format is supported.  And
  916. **| actually exporting a port requires a new destination file name and format.
  917. **|
  918. **|| tokens: a port supports queries about atomized strings to map tokens to
  919. **| strings or strings to token integers.  (All atomized strings must be in
  920. **| US-ASCII iso-8859-1 Latin1 charset encoding.)  When a port is actually a
  921. **| mutable store and a string has not yet been atomized, then StringToToken()
  922. **| will actually do so and modify the store.  The QueryToken() method will not
  923. **| atomize a string if it has not already been atomized yet, even in stores.
  924. **|
  925. **|| tables: other than string tokens, all port content is presented through
  926. **| tables, which are ordered collections of rows.  Tables are identified by
  927. **| row scope and table kind, which might or might not be unique in a port,
  928. **| depending on app convention.  When tables are effectively unique, then
  929. **| queries for specific scope and kind pairs will find those tables.  To see
  930. **| all tables that match specific row scope and table kind patterns, even in
  931. **| the presence of duplicates, every port supports a GetPortTableCursor()
  932. **| method that returns an iterator over all matching tables.  Table kind is
  933. **| considered scoped inside row scope, so passing a zero for table kind will
  934. **| find all table kinds for some nonzero row scope.  Passing a zero for row
  935. **| scope will iterate over all tables in the port, in some undefined order.
  936. **| (A new table can be added to a port using nsIMdbStore::NewTable(), even when
  937. **| the requested scope and kind combination is already used by other tables.)
  938. **|
  939. **|| memory: callers can request that a database use less memory footprint in
  940. **| several flavors, from an inconsequential idle flavor to a rather drastic
  941. **| panic flavor. Callers might perform an idle purge very frequently if desired
  942. **| with very little cost, since only normally scheduled memory management will
  943. **| be conducted, such as freeing resources for objects scheduled to be dropped.
  944. **| Callers should perform session memory purges infrequently because they might
  945. **| involve costly scanning of data structures to removed cached content, and
  946. **| session purges are recommended only when a caller experiences memory crunch.
  947. **| Callers should only rarely perform a panic purge, in response to dire memory
  948. **| straits, since this is likely to make db operations much more expensive
  949. **| than they would be otherwise.  A panic purge asks a database to free as much
  950. **| memory as possible while staying effective and operational, because a caller
  951. **| thinks application failure might otherwise occur.  (Apps might better close
  952. **| an open db, so panic purges only make sense when a db is urgently needed.)
  953. |*/
  954. class nsIMdbPort : public nsISupports {
  955. public:
  956.  
  957. // { ===== begin nsIMdbPort methods =====
  958.  
  959.   // { ----- begin attribute methods -----
  960.   NS_IMETHOD GetIsPortReadonly(nsIMdbEnv* ev, mdb_bool* outBool) = 0;
  961.   NS_IMETHOD GetIsStore(nsIMdbEnv* ev, mdb_bool* outBool) = 0;
  962.   NS_IMETHOD GetIsStoreAndDirty(nsIMdbEnv* ev, mdb_bool* outBool) = 0;
  963.  
  964.   NS_IMETHOD GetUsagePolicy(nsIMdbEnv* ev, 
  965.     mdbUsagePolicy* ioUsagePolicy) = 0;
  966.  
  967.   NS_IMETHOD SetUsagePolicy(nsIMdbEnv* ev, 
  968.     const mdbUsagePolicy* inUsagePolicy) = 0;
  969.   // } ----- end attribute methods -----
  970.  
  971.   // { ----- begin memory policy methods -----  
  972.   NS_IMETHOD IdleMemoryPurge( // do memory management already scheduled
  973.     nsIMdbEnv* ev, // context
  974.     mdb_size* outEstimatedBytesFreed) = 0; // approximate bytes actually freed
  975.  
  976.   NS_IMETHOD SessionMemoryPurge( // request specific footprint decrease
  977.     nsIMdbEnv* ev, // context
  978.     mdb_size inDesiredBytesFreed, // approximate number of bytes wanted
  979.     mdb_size* outEstimatedBytesFreed) = 0; // approximate bytes actually freed
  980.  
  981.   NS_IMETHOD PanicMemoryPurge( // desperately free all possible memory
  982.     nsIMdbEnv* ev, // context
  983.     mdb_size* outEstimatedBytesFreed) = 0; // approximate bytes actually freed
  984.   // } ----- end memory policy methods -----
  985.  
  986.   // { ----- begin filepath methods -----
  987.   NS_IMETHOD GetPortFilePath(
  988.     nsIMdbEnv* ev, // context
  989.     mdbYarn* outFilePath, // name of file holding port content
  990.     mdbYarn* outFormatVersion) = 0; // file format description
  991.     
  992.   NS_IMETHOD GetPortFile(
  993.     nsIMdbEnv* ev, // context
  994.     nsIMdbFile** acqFile) = 0; // acquire file used by port or store
  995.   // } ----- end filepath methods -----
  996.  
  997.   // { ----- begin export methods -----
  998.   NS_IMETHOD BestExportFormat( // determine preferred export format
  999.     nsIMdbEnv* ev, // context
  1000.     mdbYarn* outFormatVersion) = 0; // file format description
  1001.  
  1002.   // some tentative suggested import/export formats
  1003.   // "ns:msg:db:port:format:ldif:ns4.0:passthrough" // necessary
  1004.   // "ns:msg:db:port:format:ldif:ns4.5:utf8"        // necessary
  1005.   // "ns:msg:db:port:format:ldif:ns4.5:tabbed"
  1006.   // "ns:msg:db:port:format:ldif:ns4.5:binary"      // necessary
  1007.   // "ns:msg:db:port:format:html:ns3.0:addressbook" // necessary
  1008.   // "ns:msg:db:port:format:html:display:verbose"
  1009.   // "ns:msg:db:port:format:html:display:concise"
  1010.   // "ns:msg:db:port:format:mork:zany:verbose"      // necessary
  1011.   // "ns:msg:db:port:format:mork:zany:atomized"     // necessary
  1012.   // "ns:msg:db:port:format:rdf:xml"
  1013.   // "ns:msg:db:port:format:xml:mork"
  1014.   // "ns:msg:db:port:format:xml:display:verbose"
  1015.   // "ns:msg:db:port:format:xml:display:concise"
  1016.   // "ns:msg:db:port:format:xml:print:verbose"      // recommended
  1017.   // "ns:msg:db:port:format:xml:print:concise"
  1018.  
  1019.   NS_IMETHOD
  1020.   CanExportToFormat( // can export content in given specific format?
  1021.     nsIMdbEnv* ev, // context
  1022.     const char* inFormatVersion, // file format description
  1023.     mdb_bool* outCanExport) = 0; // whether ExportSource() might succeed
  1024.  
  1025.   NS_IMETHOD ExportToFormat( // export content in given specific format
  1026.     nsIMdbEnv* ev, // context
  1027.     // const char* inFilePath, // the file to receive exported content
  1028.     nsIMdbFile* ioFile, // destination abstract file interface
  1029.     const char* inFormatVersion, // file format description
  1030.     nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental export
  1031.   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  1032.   // then the export will be finished.
  1033.  
  1034.   // } ----- end export methods -----
  1035.  
  1036.   // { ----- begin token methods -----
  1037.   NS_IMETHOD TokenToString( // return a string name for an integer token
  1038.     nsIMdbEnv* ev, // context
  1039.     mdb_token inToken, // token for inTokenName inside this port
  1040.     mdbYarn* outTokenName) = 0; // the type of table to access
  1041.   
  1042.   NS_IMETHOD StringToToken( // return an integer token for scope name
  1043.     nsIMdbEnv* ev, // context
  1044.     const char* inTokenName, // Latin1 string to tokenize if possible
  1045.     mdb_token* outToken) = 0; // token for inTokenName inside this port
  1046.     
  1047.   // String token zero is never used and never supported. If the port
  1048.   // is a mutable store, then StringToToken() to create a new
  1049.   // association of inTokenName with a new integer token if possible.
  1050.   // But a readonly port will return zero for an unknown scope name.
  1051.  
  1052.   NS_IMETHOD QueryToken( // like StringToToken(), but without adding
  1053.     nsIMdbEnv* ev, // context
  1054.     const char* inTokenName, // Latin1 string to tokenize if possible
  1055.     mdb_token* outToken) = 0; // token for inTokenName inside this port
  1056.   
  1057.   // QueryToken() will return a string token if one already exists,
  1058.   // but unlike StringToToken(), will not assign a new token if not
  1059.   // already in use.
  1060.  
  1061.   // } ----- end token methods -----
  1062.  
  1063.   // { ----- begin row methods -----  
  1064.   NS_IMETHOD HasRow( // contains a row with the specified oid?
  1065.     nsIMdbEnv* ev, // context
  1066.     const mdbOid* inOid,  // hypothetical row oid
  1067.     mdb_bool* outHasRow) = 0; // whether GetRow() might succeed
  1068.  
  1069.   NS_IMETHOD GetRowRefCount( // get number of tables that contain a row 
  1070.     nsIMdbEnv* ev, // context
  1071.     const mdbOid* inOid,  // hypothetical row oid
  1072.     mdb_count* outRefCount) = 0; // number of tables containing inRowKey 
  1073.     
  1074.   NS_IMETHOD GetRow( // access one row with specific oid
  1075.     nsIMdbEnv* ev, // context
  1076.     const mdbOid* inOid,  // hypothetical row oid
  1077.     nsIMdbRow** acqRow) = 0; // acquire specific row (or null)
  1078.     
  1079.   // NS_IMETHOD
  1080.   // GetPortRowCursor( // get cursor for all rows in specific scope
  1081.   //   nsIMdbEnv* ev, // context
  1082.   //   mdb_scope inRowScope, // row scope for row ids
  1083.   //   nsIMdbPortRowCursor** acqCursor) = 0; // all such rows in the port
  1084.  
  1085.   NS_IMETHOD FindRow(nsIMdbEnv* ev, // search for row with matching cell
  1086.     mdb_scope inRowScope,   // row scope for row ids
  1087.     mdb_column inColumn,   // the column to search (and maintain an index)
  1088.     const mdbYarn* inTargetCellValue, // cell value for which to search
  1089.     mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match)
  1090.     nsIMdbRow** acqRow) = 0; // acquire matching row (or nil for no match)
  1091.                              // can be null if you only want the oid
  1092.   // FindRow() searches for one row that has a cell in column inColumn with
  1093.   // a contained value with the same form (i.e. charset) and is byte-wise
  1094.   // identical to the blob described by yarn inTargetCellValue.  Both content
  1095.   // and form of the yarn must be an exact match to find a matching row.
  1096.   //
  1097.   // (In other words, both a yarn's blob bytes and form are significant.  The
  1098.   // form is not expected to vary in columns used for identity anyway.  This
  1099.   // is intended to make the cost of FindRow() cheaper for MDB implementors,
  1100.   // since any cell value atomization performed internally must necessarily
  1101.   // make yarn form significant in order to avoid data loss in atomization.)
  1102.   //
  1103.   // FindRow() can lazily create an index on attribute inColumn for all rows
  1104.   // with that attribute in row space scope inRowScope, so that subsequent
  1105.   // calls to FindRow() will perform faster.  Such an index might or might
  1106.   // not be persistent (but this seems desirable if it is cheap to do so).
  1107.   // Note that lazy index creation in readonly DBs is not very feasible.
  1108.   //
  1109.   // This FindRow() interface assumes that attribute inColumn is effectively
  1110.   // an alternative means of unique identification for a row in a rowspace,
  1111.   // so correct behavior is only guaranteed when no duplicates for this col
  1112.   // appear in the given set of rows.  (If more than one row has the same cell
  1113.   // value in this column, no more than one will be found; and cutting one of
  1114.   // two duplicate rows can cause the index to assume no other such row lives
  1115.   // in the row space, so future calls return nil for negative search results
  1116.   // even though some duplicate row might still live within the rowspace.)
  1117.   //
  1118.   // In other words, the FindRow() implementation is allowed to assume simple
  1119.   // hash tables mapping unqiue column keys to associated row values will be
  1120.   // sufficient, where any duplication is not recorded because only one copy
  1121.   // of a given key need be remembered.  Implementors are not required to sort
  1122.   // all rows by the specified column.
  1123.   // } ----- end row methods -----
  1124.  
  1125.   // { ----- begin table methods -----  
  1126.   NS_IMETHOD HasTable( // supports a table with the specified oid?
  1127.     nsIMdbEnv* ev, // context
  1128.     const mdbOid* inOid,  // hypothetical table oid
  1129.     mdb_bool* outHasTable) = 0; // whether GetTable() might succeed
  1130.     
  1131.   NS_IMETHOD GetTable( // access one table with specific oid
  1132.     nsIMdbEnv* ev, // context
  1133.     const mdbOid* inOid,  // hypothetical table oid
  1134.     nsIMdbTable** acqTable) = 0; // acquire specific table (or null)
  1135.   
  1136.   NS_IMETHOD HasTableKind( // supports a table of the specified type?
  1137.     nsIMdbEnv* ev, // context
  1138.     mdb_scope inRowScope, // rid scope for row ids
  1139.     mdb_kind inTableKind, // the type of table to access
  1140.     mdb_count* outTableCount, // current number of such tables
  1141.     mdb_bool* outSupportsTable) = 0; // whether GetTableKind() might succeed
  1142.     
  1143.   // row scopes to be supported include the following suggestions:
  1144.   // "ns:msg:db:row:scope:address:cards:all"
  1145.   // "ns:msg:db:row:scope:mail:messages:all"
  1146.   // "ns:msg:db:row:scope:news:articles:all"
  1147.  
  1148.   // table kinds to be supported include the following suggestions:
  1149.   // "ns:msg:db:table:kind:address:cards:main"
  1150.   // "ns:msg:db:table:kind:address:lists:all" 
  1151.   // "ns:msg:db:table:kind:address:list" 
  1152.   // "ns:msg:db:table:kind:news:threads:all" 
  1153.   // "ns:msg:db:table:kind:news:thread" 
  1154.   // "ns:msg:db:table:kind:mail:threads:all"
  1155.   // "ns:msg:db:table:kind:mail:thread"
  1156.     
  1157.   NS_IMETHOD GetTableKind( // access one (random) table of specific type
  1158.     nsIMdbEnv* ev, // context
  1159.     mdb_scope inRowScope,      // row scope for row ids
  1160.     mdb_kind inTableKind,      // the type of table to access
  1161.     mdb_count* outTableCount, // current number of such tables
  1162.     mdb_bool* outMustBeUnique, // whether port can hold only one of these
  1163.     nsIMdbTable** acqTable) = 0;       // acquire scoped collection of rows
  1164.     
  1165.   NS_IMETHOD
  1166.   GetPortTableCursor( // get cursor for all tables of specific type
  1167.     nsIMdbEnv* ev, // context
  1168.     mdb_scope inRowScope, // row scope for row ids
  1169.     mdb_kind inTableKind, // the type of table to access
  1170.     nsIMdbPortTableCursor** acqCursor) = 0; // all such tables in the port
  1171.   // } ----- end table methods -----
  1172.  
  1173.  
  1174.   // { ----- begin commit methods -----
  1175.  
  1176.   NS_IMETHOD ShouldCompress( // store wastes at least inPercentWaste?
  1177.     nsIMdbEnv* ev, // context
  1178.     mdb_percent inPercentWaste, // 0..100 percent file size waste threshold
  1179.     mdb_percent* outActualWaste, // 0..100 percent of file actually wasted
  1180.     mdb_bool* outShould) = 0; // true when about inPercentWaste% is wasted
  1181.   // ShouldCompress() returns true if the store can determine that the file
  1182.   // will shrink by an estimated percentage of inPercentWaste% (or more) if
  1183.   // CompressCommit() is called, because that percentage of the file seems
  1184.   // to be recoverable free space.  The granularity is only in terms of 
  1185.   // percentage points, and any value over 100 is considered equal to 100.
  1186.   //
  1187.   // If a store only has an approximate idea how much space might be saved
  1188.   // during a compress, then a best guess should be made.  For example, the
  1189.   // Mork implementation might keep track of how much file space began with
  1190.   // text content before the first updating transaction, and then consider
  1191.   // all content following the start of the first transaction as potentially
  1192.   // wasted space if it is all updates and not just new content.  (This is
  1193.   // a safe assumption in the sense that behavior will stabilize on a low
  1194.   // estimate of wastage after a commit removes all transaction updates.)
  1195.   //
  1196.   // Some db formats might attempt to keep a very accurate reckoning of free
  1197.   // space size, so a very accurate determination can be made.  But other db
  1198.   // formats might have difficulty determining size of free space, and might
  1199.   // require some lengthy calculation to answer.  This is the reason for
  1200.   // passing in the percentage threshold of interest, so that such lengthy
  1201.   // computations can terminate early as soon as at least inPercentWaste is
  1202.   // found, so that the entire file need not be groveled when unnecessary.
  1203.   // However, we hope implementations will always favor fast but imprecise
  1204.   // heuristic answers instead of extremely slow but very precise answers.
  1205.   //
  1206.   // If the outActualWaste parameter is non-nil, it will be used to return
  1207.   // the actual estimated space wasted as a percentage of file size.  (This
  1208.   // parameter is provided so callers need not call repeatedly with altered
  1209.   // inPercentWaste values to isolate the actual wastage figure.)  Note the
  1210.   // actual wastage figure returned can exactly equal inPercentWaste even
  1211.   // when this grossly underestimates the real figure involved, if the db
  1212.   // finds it very expensive to determine the extent of wastage after it is
  1213.   // known to at least exceed inPercentWaste.  Note we expect that whenever
  1214.   // outShould returns true, that outActualWaste returns >= inPercentWaste.
  1215.   //
  1216.   // The effect of different inPercentWaste values is not very uniform over
  1217.   // the permitted range.  For example, 50 represents 50% wastage, or a file
  1218.   // that is about double what it should be ideally.  But 99 represents 99%
  1219.   // wastage, or a file that is about ninety-nine times as big as it should
  1220.   // be ideally.  In the smaller direction, 25 represents 25% wastage, or
  1221.   // a file that is only 33% larger than it should be ideally.
  1222.   //
  1223.   // Callers can determine what policy they want to use for considering when
  1224.   // a file holds too much wasted space, and express this as a percentage
  1225.   // of total file size to pass as in the inPercentWaste parameter.  A zero
  1226.   // likely returns always trivially true, and 100 always trivially false.
  1227.   // The great majority of callers are expected to use values from 25 to 75,
  1228.   // since most plausible thresholds for compressing might fall between the
  1229.   // extremes of 133% of ideal size and 400% of ideal size.  (Presumably the
  1230.   // larger a file gets, the more important the percentage waste involved, so
  1231.   // a sliding scale for compress thresholds might use smaller numbers for
  1232.   // much bigger file sizes.)
  1233.   
  1234.   // } ----- end commit methods -----
  1235.  
  1236. // } ===== end nsIMdbPort methods =====
  1237. };
  1238.  
  1239. /*| nsIMdbStore: a mutable interface to a specific database file.
  1240. **|
  1241. **|| tables: one can force a new table to exist in a store with NewTable()
  1242. **| and nonzero values for both row scope and table kind.  (If one wishes only
  1243. **| one table of a certain kind, then one might look for it first using the
  1244. **| GetTableKind() method).  One can pass inMustBeUnique to force future
  1245. **| users of this store to be unable to create other tables with the same pair
  1246. **| of scope and kind attributes.  When inMustBeUnique is true, and the table
  1247. **| with the given scope and kind pair already exists, then the existing one
  1248. **| is returned instead of making a new table.  Similarly, if one passes false
  1249. **| for inMustBeUnique, but the table kind has already been marked unique by a
  1250. **| previous user of the store, then the existing unique table is returned.
  1251. **|
  1252. **|| import: all or some of another port's content can be imported by calling
  1253. **| AddPortContent() with a row scope identifying the extent of content to
  1254. **| be imported.  A zero row scope will import everything.  A nonzero row
  1255. **| scope will only import tables with a matching row scope.  Note that one
  1256. **| must somehow find a way to negotiate possible conflicts between existing
  1257. **| row content and imported row content, and this involves a specific kind of
  1258. **| definition for row identity involving either row IDs or unique attributes,
  1259. **| or some combination of these two.  At the moment I am just going to wave
  1260. **| my hands, and say the default behavior is to assign all new row identities
  1261. **| to all imported content, which will result in no merging of content; this
  1262. **| must change later because it is unacceptable in some contexts.
  1263. **|
  1264. **|| commits: to manage modifications in a mutable store, very few methods are
  1265. **| really needed to indicate global policy choices that are independent of 
  1266. **| the actual modifications that happen in objects at the level of tables,
  1267. **| rows, and cells, etc.  The most important policy to specify is which sets
  1268. **| of changes are considered associated in a manner such that they should be
  1269. **| applied together atomically to a given store.  We call each such group of
  1270. **| changes a transaction.  We handle three different grades of transaction,
  1271. **| but they differ only in semantic significance to the application, and are
  1272. **| not intended to nest.  (If small transactions were nested inside large
  1273. **| transactions, that would imply that a single large transaction must be
  1274. **| atomic over all the contained small transactions; but actually we intend
  1275. **| smalls transaction never be undone once commited due to, say, aborting a
  1276. **| transaction of greater significance.)  The small, large, and session level
  1277. **| commits have equal granularity, and differ only in risk of loss from the
  1278. **| perspective of an application.  Small commits characterize changes that
  1279. **| can be lost with relatively small risk, so small transactions can delay
  1280. **| until later if they are expensive or impractical to commit.  Large commits
  1281. **| involve changes that would probably inconvenience users if lost, so the
  1282. **| need to pay costs of writing is rather greater than with small commits.
  1283. **| Session commits are last ditch attempts to save outstanding changes before
  1284. **| stopping the use of a particular database, so there will be no later point
  1285. **| in time to save changes that have been delayed due to possible high cost.
  1286. **| If large commits are never delayed, then a session commit has about the
  1287. **| same performance effect as another large commit; but if small and large
  1288. **| commits are always delayed, then a session commit is likely to be rather
  1289. **| expensive as a runtime cost compared to any earlier database usage.
  1290. **|
  1291. **|| aborts: the only way to abort changes to a store is by closing the store.
  1292. **| So there is no specific method for causing any abort.  Stores must discard
  1293. **| all changes made that are uncommited when a store is closed.  This design
  1294. **| choice makes the implementations of tables, rows, and cells much less
  1295. **| complex because they need not maintain a record of undobable changes.  When
  1296. **| a store is closed, presumably this precipitates the closure of all tables,
  1297. **| rows, and cells in the store as well.   So an application can revert the
  1298. **| state of a store in the user interface by quietly closing and reopening a
  1299. **| store, because this will discard uncommited changes and show old content.
  1300. **| This implies an app that closes a store will need to send a "scramble"
  1301. **| event notification to any views that depend on old discarded content.
  1302. |*/
  1303.  
  1304. #define NS_IMDBSTORE_IID_STR "726618d3-f15b-49b9-9f4a-efcc9db53d0d"
  1305.  
  1306. #define NS_IMDBSTORE_IID \
  1307. {0x726618d3, 0xf15b, 0x49b9, \
  1308. {0x9f, 0x4a, 0xef, 0xcc, 0x9d, 0xb5, 0x3d, 0x0d}}
  1309.  
  1310. class nsIMdbStore : public nsIMdbPort {
  1311. public:
  1312.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBSTORE_IID)
  1313.  
  1314. // { ===== begin nsIMdbStore methods =====
  1315.  
  1316.   // { ----- begin table methods -----
  1317.   NS_IMETHOD NewTable( // make one new table of specific type
  1318.     nsIMdbEnv* ev, // context
  1319.     mdb_scope inRowScope,    // row scope for row ids
  1320.     mdb_kind inTableKind,    // the type of table to access
  1321.     mdb_bool inMustBeUnique, // whether store can hold only one of these
  1322.     const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
  1323.     nsIMdbTable** acqTable) = 0;     // acquire scoped collection of rows
  1324.     
  1325.   NS_IMETHOD NewTableWithOid( // make one new table of specific type
  1326.     nsIMdbEnv* ev, // context
  1327.     const mdbOid* inOid,   // caller assigned oid
  1328.     mdb_kind inTableKind,    // the type of table to access
  1329.     mdb_bool inMustBeUnique, // whether store can hold only one of these
  1330.     const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying 
  1331.     nsIMdbTable** acqTable) = 0;     // acquire scoped collection of rows
  1332.   // } ----- end table methods -----
  1333.  
  1334.   // { ----- begin row scope methods -----
  1335.   NS_IMETHOD RowScopeHasAssignedIds(nsIMdbEnv* ev,
  1336.     mdb_scope inRowScope,   // row scope for row ids
  1337.     mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
  1338.     mdb_bool* outStoreAssigned) = 0; // nonzero if store db assigned specified
  1339.  
  1340.   NS_IMETHOD SetCallerAssignedIds(nsIMdbEnv* ev,
  1341.     mdb_scope inRowScope,   // row scope for row ids
  1342.     mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
  1343.     mdb_bool* outStoreAssigned) = 0; // nonzero if store db assigned specified
  1344.  
  1345.   NS_IMETHOD SetStoreAssignedIds(nsIMdbEnv* ev,
  1346.     mdb_scope inRowScope,   // row scope for row ids
  1347.     mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
  1348.     mdb_bool* outStoreAssigned) = 0; // nonzero if store db assigned specified
  1349.   // } ----- end row scope methods -----
  1350.  
  1351.   // { ----- begin row methods -----
  1352.   NS_IMETHOD NewRowWithOid(nsIMdbEnv* ev, // new row w/ caller assigned oid
  1353.     const mdbOid* inOid,   // caller assigned oid
  1354.     nsIMdbRow** acqRow) = 0; // create new row
  1355.  
  1356.   NS_IMETHOD NewRow(nsIMdbEnv* ev, // new row with db assigned oid
  1357.     mdb_scope inRowScope,   // row scope for row ids
  1358.     nsIMdbRow** acqRow) = 0; // create new row
  1359.   // Note this row must be added to some table or cell child before the
  1360.   // store is closed in order to make this row persist across sesssions.
  1361.  
  1362.   // } ----- end row methods -----
  1363.  
  1364.   // { ----- begin inport/export methods -----
  1365.   NS_IMETHOD ImportContent( // import content from port
  1366.     nsIMdbEnv* ev, // context
  1367.     mdb_scope inRowScope, // scope for rows (or zero for all?)
  1368.     nsIMdbPort* ioPort, // the port with content to add to store
  1369.     nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental import
  1370.   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  1371.   // then the import will be finished.
  1372.  
  1373.   NS_IMETHOD ImportFile( // import content from port
  1374.     nsIMdbEnv* ev, // context
  1375.     nsIMdbFile* ioFile, // the file with content to add to store
  1376.     nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental import
  1377.   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  1378.   // then the import will be finished.
  1379.   // } ----- end inport/export methods -----
  1380.  
  1381.   // { ----- begin hinting methods -----
  1382.   NS_IMETHOD
  1383.   ShareAtomColumnsHint( // advise re shared column content atomizing
  1384.     nsIMdbEnv* ev, // context
  1385.     mdb_scope inScopeHint, // zero, or suggested shared namespace
  1386.     const mdbColumnSet* inColumnSet) = 0; // cols desired tokenized together
  1387.  
  1388.   NS_IMETHOD
  1389.   AvoidAtomColumnsHint( // advise column with poor atomizing prospects
  1390.     nsIMdbEnv* ev, // context
  1391.     const mdbColumnSet* inColumnSet) = 0; // cols with poor atomizing prospects
  1392.   // } ----- end hinting methods -----
  1393.  
  1394.   // { ----- begin commit methods -----
  1395.   NS_IMETHOD SmallCommit( // save minor changes if convenient and uncostly
  1396.     nsIMdbEnv* ev) = 0; // context
  1397.   
  1398.   NS_IMETHOD LargeCommit( // save important changes if at all possible
  1399.     nsIMdbEnv* ev, // context
  1400.     nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental commit
  1401.   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  1402.   // then the commit will be finished.  Note the store is effectively write
  1403.   // locked until commit is finished or canceled through the thumb instance.
  1404.   // Until the commit is done, the store will report it has readonly status.
  1405.  
  1406.   NS_IMETHOD SessionCommit( // save all changes if large commits delayed
  1407.     nsIMdbEnv* ev, // context
  1408.     nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental commit
  1409.   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  1410.   // then the commit will be finished.  Note the store is effectively write
  1411.   // locked until commit is finished or canceled through the thumb instance.
  1412.   // Until the commit is done, the store will report it has readonly status.
  1413.  
  1414.   NS_IMETHOD
  1415.   CompressCommit( // commit and make db physically smaller if possible
  1416.     nsIMdbEnv* ev, // context
  1417.     nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental commit
  1418.   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  1419.   // then the commit will be finished.  Note the store is effectively write
  1420.   // locked until commit is finished or canceled through the thumb instance.
  1421.   // Until the commit is done, the store will report it has readonly status.
  1422.   
  1423.   // } ----- end commit methods -----
  1424.  
  1425. // } ===== end nsIMdbStore methods =====
  1426. };
  1427.  
  1428. /*| nsIMdbCursor: base cursor class for iterating row cells and table rows
  1429. **|
  1430. **|| count: the number of elements in the collection (table or row)
  1431. **|
  1432. **|| seed: the change count in the underlying collection, which is synced
  1433. **| with the collection when the iteration position is set, and henceforth
  1434. **| acts to show whether the iter has lost collection synchronization, in
  1435. **| case it matters to clients whether any change happens during iteration.
  1436. **|
  1437. **|| pos: the position of the current element in the collection.  Negative
  1438. **| means a position logically before the first element.  A positive value
  1439. **| equal to count (or larger) implies a position after the last element.
  1440. **| To iterate over all elements, set the position to negative, so subsequent
  1441. **| calls to any 'next' method will access the first collection element.
  1442. **|
  1443. **|| doFailOnSeedOutOfSync: whether a cursor should return an error if the
  1444. **| cursor's snapshot of a table's seed becomes stale with respect the table's
  1445. **| current seed value (which implies the iteration is less than total) in
  1446. **| between to cursor calls that actually access collection content.  By
  1447. **| default, a cursor should assume this attribute is false until specified,
  1448. **| so that iterations quietly try to re-sync when they loose coherence.
  1449. |*/
  1450.  
  1451. #define NS_IMDBCURSOR_IID_STR "a0c37337-6ebc-474c-90db-e65ea0b850aa"
  1452.  
  1453. #define NS_IMDBCURSOR_IID \
  1454. {0xa0c37337, 0x6ebc, 0x474c, \
  1455. {0x90, 0xdb, 0xe6, 0x5e, 0xa0, 0xb8, 0x50, 0xaa}}
  1456.  
  1457. class nsIMdbCursor  : public nsISupports  { // collection iterator
  1458. public:
  1459.  
  1460.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBCURSOR_IID)
  1461. // { ===== begin nsIMdbCursor methods =====
  1462.  
  1463.   // { ----- begin attribute methods -----
  1464.   NS_IMETHOD GetCount(nsIMdbEnv* ev, mdb_count* outCount) = 0; // readonly
  1465.   NS_IMETHOD GetSeed(nsIMdbEnv* ev, mdb_seed* outSeed) = 0;    // readonly
  1466.   
  1467.   NS_IMETHOD SetPos(nsIMdbEnv* ev, mdb_pos inPos) = 0;   // mutable
  1468.   NS_IMETHOD GetPos(nsIMdbEnv* ev, mdb_pos* outPos) = 0;
  1469.   
  1470.   NS_IMETHOD SetDoFailOnSeedOutOfSync(nsIMdbEnv* ev, mdb_bool inFail) = 0;
  1471.   NS_IMETHOD GetDoFailOnSeedOutOfSync(nsIMdbEnv* ev, mdb_bool* outFail) = 0;
  1472.   // } ----- end attribute methods -----
  1473.  
  1474. // } ===== end nsIMdbCursor methods =====
  1475. };
  1476.  
  1477. #define NS_IMDBPORTTABLECURSOR_IID_STR = "f181a41e-933d-49b3-af93-20d3634b8b78"
  1478.  
  1479. #define NS_IMDBPORTTABLECURSOR_IID \
  1480. {0xf181a41e, 0x933d, 0x49b3, \
  1481. {0xaf, 0x93, 0x20, 0xd3, 0x63, 0x4b, 0x8b, 0x78}}
  1482.  
  1483. /*| nsIMdbPortTableCursor: cursor class for iterating port tables
  1484. **|
  1485. **|| port: the cursor is associated with a specific port, which can be
  1486. **| set to a different port (which resets the position to -1 so the
  1487. **| next table acquired is the first in the port.
  1488. **|
  1489. |*/
  1490. class nsIMdbPortTableCursor : public nsISupports { // table collection iterator
  1491. public:
  1492.  
  1493.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBPORTTABLECURSOR_IID)
  1494. // { ===== begin nsIMdbPortTableCursor methods =====
  1495.  
  1496.   // { ----- begin attribute methods -----
  1497.   NS_IMETHOD SetPort(nsIMdbEnv* ev, nsIMdbPort* ioPort) = 0; // sets pos to -1
  1498.   NS_IMETHOD GetPort(nsIMdbEnv* ev, nsIMdbPort** acqPort) = 0;
  1499.   
  1500.   NS_IMETHOD SetRowScope(nsIMdbEnv* ev, // sets pos to -1
  1501.     mdb_scope inRowScope) = 0;
  1502.   NS_IMETHOD GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope) = 0; 
  1503.   // setting row scope to zero iterates over all row scopes in port
  1504.     
  1505.   NS_IMETHOD SetTableKind(nsIMdbEnv* ev, // sets pos to -1
  1506.     mdb_kind inTableKind) = 0;
  1507.   NS_IMETHOD GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind) = 0;
  1508.   // setting table kind to zero iterates over all table kinds in row scope
  1509.   // } ----- end attribute methods -----
  1510.  
  1511.   // { ----- begin table iteration methods -----
  1512.   NS_IMETHOD NextTable( // get table at next position in the db
  1513.     nsIMdbEnv* ev, // context
  1514.     nsIMdbTable** acqTable) = 0; // the next table in the iteration
  1515.   // } ----- end table iteration methods -----
  1516.  
  1517. // } ===== end nsIMdbPortTableCursor methods =====
  1518. };
  1519.  
  1520. /*| nsIMdbCollection: an object that collects a set of other objects as members.
  1521. **| The main purpose of this base class is to unify the perceived semantics
  1522. **| of tables and rows where their collection behavior is similar.  This helps
  1523. **| isolate the mechanics of collection behavior from the other semantics that
  1524. **| are more characteristic of rows and tables.
  1525. **|
  1526. **|| count: the number of objects in a collection is the member count. (Some
  1527. **| collection interfaces call this attribute the 'size', but that can be a
  1528. **| little ambiguous, and counting actual members is harder to confuse.)
  1529. **|
  1530. **|| seed: the seed of a collection is a counter for changes in membership in
  1531. **| a specific collection.  This seed should change when members are added to
  1532. **| or removed from a collection, but not when a member changes internal state.
  1533. **| The seed should also change whenever the internal collection of members has
  1534. **| a complex state change that reorders member positions (say by sorting) that
  1535. **| would affect the nature of an iteration over that collection of members.
  1536. **| The purpose of a seed is to inform any outstanding collection cursors that
  1537. **| they might be stale, without incurring the cost of broadcasting an event
  1538. **| notification to such cursors, which would need more data structure support.
  1539. **| Presumably a cursor in a particular mdb code suite has much more direct
  1540. **| access to a collection seed member slot that this abstract COM interface,
  1541. **| so this information is intended more for clients outside mdb that want to
  1542. **| make inferences similar to those made by the collection cursors.  The seed
  1543. **| value as an integer magnitude is not very important, and callers should not
  1544. **| assume meaningful information can be derived from an integer value beyond
  1545. **| whether it is equal or different from a previous inspection.  A seed uses
  1546. **| integers of many bits in order to make the odds of wrapping and becoming
  1547. **| equal to an earlier seed value have probability that is vanishingly small.
  1548. **|
  1549. **|| port: every collection is associated with a specific database instance.
  1550. **|
  1551. **|| cursor: a subclass of nsIMdbCursor suitable for this specific collection
  1552. **| subclass.  The ability to GetCursor() from the base nsIMdbCollection class
  1553. **| is not really as useful as getting a more specifically typed cursor more
  1554. **| directly from the base class without any casting involved.  So including
  1555. **| this method here is more for conceptual illustration.
  1556. **|
  1557. **|| oid: every collection has an identity that persists from session to
  1558. **| session. Implementations are probably able to distinguish row IDs from
  1559. **| table IDs, but we don't specify anything official in this regard.  A
  1560. **| collection has the same identity for the lifetime of the collection,
  1561. **| unless identity is swapped with another collection by means of a call to
  1562. **| BecomeContent(), which is considered a way to swap a new representation
  1563. **| for an old well-known object.  (Even so, only content appears to change,
  1564. **| while the identity seems to stay the same.)
  1565. **|
  1566. **|| become: developers can effectively cause two objects to swap identities,
  1567. **| in order to effect a complete swap between what persistent content is
  1568. **| represented by two oids.  The caller should consider this a content swap,
  1569. **| and not identity wap, because identities will seem to stay the same while
  1570. **| only content changes.  However, implementations will likely do this
  1571. **| internally by swapping identities.  Callers must swap content only
  1572. **| between objects of similar type, such as a row with another row, and a
  1573. **| table with another table, because implementations need not support
  1574. **| cross-object swapping because it might break object name spaces.
  1575. **|
  1576. **|| dropping: when a caller expects a row or table will no longer be used, the
  1577. **| caller can tell the collection to 'drop activity', which means the runtime
  1578. **| object can have it's internal representation purged to save memory or any
  1579. **| other resource that is being consumed by the collection's representation.
  1580. **| This has no effect on the collection's persistent content or semantics,
  1581. **| and is only considered a runtime effect.  After a collection drops
  1582. **| activity, the object should still be as usable as before (because it has
  1583. **| NOT been closed), but further usage can be expensive to re-instate because
  1584. **| it might involve reallocating space and/or re-reading disk space.  But
  1585. **| since this future usage is not expected, the caller does not expect to
  1586. **| pay the extra expense.  An implementation can choose to implement
  1587. **| 'dropping activity' in different ways, or even not at all if this
  1588. **| operation is not really feasible.  Callers cannot ask objects whether they
  1589. **| are 'dropped' or not, so this should be transparent. (Note that
  1590. **| implementors might fear callers do not really know whether future
  1591. **| usage will occur, and therefore might delay the act of dropping until
  1592. **| the near future, until seeing whether the object is used again
  1593. **| immediately elsewhere. Such use soon after the drop request might cause
  1594. **| the drop to be cancelled.)
  1595. |*/
  1596. class nsIMdbCollection : public nsISupports { // sequence of objects
  1597. public:
  1598.  
  1599. // { ===== begin nsIMdbCollection methods =====
  1600.  
  1601.   // { ----- begin attribute methods -----
  1602.   NS_IMETHOD GetSeed(nsIMdbEnv* ev,
  1603.     mdb_seed* outSeed) = 0;    // member change count
  1604.   NS_IMETHOD GetCount(nsIMdbEnv* ev,
  1605.     mdb_count* outCount) = 0; // member count
  1606.  
  1607.   NS_IMETHOD GetPort(nsIMdbEnv* ev,
  1608.     nsIMdbPort** acqPort) = 0; // collection container
  1609.   // } ----- end attribute methods -----
  1610.  
  1611.   // { ----- begin cursor methods -----
  1612.   NS_IMETHOD GetCursor( // make a cursor starting iter at inMemberPos
  1613.     nsIMdbEnv* ev, // context
  1614.     mdb_pos inMemberPos, // zero-based ordinal pos of member in collection
  1615.     nsIMdbCursor** acqCursor) = 0; // acquire new cursor instance
  1616.   // } ----- end cursor methods -----
  1617.  
  1618.   // { ----- begin ID methods -----
  1619.   NS_IMETHOD GetOid(nsIMdbEnv* ev,
  1620.     mdbOid* outOid) = 0; // read object identity
  1621.   NS_IMETHOD BecomeContent(nsIMdbEnv* ev,
  1622.     const mdbOid* inOid) = 0; // exchange content
  1623.   // } ----- end ID methods -----
  1624.  
  1625.   // { ----- begin activity dropping methods -----
  1626.   NS_IMETHOD DropActivity( // tell collection usage no longer expected
  1627.     nsIMdbEnv* ev) = 0;
  1628.   // } ----- end activity dropping methods -----
  1629.  
  1630. // } ===== end nsIMdbCollection methods =====
  1631. };
  1632.  
  1633. /*| nsIMdbTable: an ordered collection of rows
  1634. **|
  1635. **|| row scope: an integer token for an atomized string in this database
  1636. **| that names a space for row IDs.  This attribute of a table is intended
  1637. **| as guidance metainformation that helps with searching a database for
  1638. **| tables that operate on collections of rows of the specific type.  By
  1639. **| convention, a table with a specific row scope is expected to focus on
  1640. **| containing rows that belong to that scope, however exceptions are easily
  1641. **| allowed because all rows in a table are known by both row ID and scope.
  1642. **| (A table with zero row scope is never allowed because this would make it
  1643. **| ambiguous to use a zero row scope when iterating over tables in a port to
  1644. **| indicate that all row scopes should be seen by a cursor.)
  1645. **|
  1646. **|| table kind: an integer token for an atomized string in this database
  1647. **| that names a kind of table as a subset of the associated row scope. This
  1648. **| attribute is intended as guidance metainformation to clarify the role of
  1649. **| this table with respect to other tables in the same row scope, and this
  1650. **| also helps search for such tables in a database.  By convention, a table
  1651. **| with a specific table kind has a consistent role for containing rows with
  1652. **| respect to other collections of such rows in the same row scope.  Also by
  1653. **| convention, at least one table in a row scope has a table kind purporting
  1654. **| to contain ALL the rows that belong in that row scope, so that at least
  1655. **| one table exists that allows all rows in a scope to be interated over.
  1656. **| (A table with zero table kind is never allowed because this would make it
  1657. **| ambiguous to use a zero table kind when iterating over tables in a port to
  1658. **| indicate that all table kinds in a row scope should be seen by a cursor.)
  1659. **|
  1660. **|| port: every table is considered part of some port that contains the
  1661. **| table, so that closing the containing port will cause the table to be
  1662. **| indirectly closed as well.  We make it easy to get the containing port for
  1663. **| a table, because the port supports important semantic interfaces that will
  1664. **| affect how content in table is presented; the most important port context
  1665. **| that affects a table is specified by the set of token to string mappings
  1666. **| that affect all tokens used throughout the database, and which drive the
  1667. **| meanings of row scope, table kind, cell columns, etc.
  1668. **|
  1669. **|| cursor: a cursor that iterates over the rows in this table, where rows
  1670. **| have zero-based index positions from zero to count-1.  Making a cursor
  1671. **| with negative position will next iterate over the first row in the table.
  1672. **|
  1673. **|| position: given any position from zero to count-1, a table will return
  1674. **| the row ID and row scope for the row at that position.  (One can use the
  1675. **| GetRowAllCells() method to read that row, or else use a row cursor to both
  1676. **| get the row at some position and read its content at the same time.)  The
  1677. **| position depends on whether a table is sorted, and upon the actual sort.
  1678. **| Note that moving a row's position is only possible in unsorted tables.
  1679. **|
  1680. **|| row set: every table contains a collection of rows, where a member row is
  1681. **| referenced by the table using the row ID and row scope for the row.  No
  1682. **| single table owns a given row instance, because rows are effectively ref-
  1683. **| counted and destroyed only when the last table removes a reference to that
  1684. **| particular row.  (But a row can be emptied of all content no matter how
  1685. **| many refs exist, and this might be the next best thing to destruction.)
  1686. **| Once a row exists in a least one table (after NewRow() is called), then it
  1687. **| can be added to any other table by calling AddRow(), or removed from any
  1688. **| table by calling CutRow(), or queried as a member by calling HasRow().  A
  1689. **| row can only be added to a table once, and further additions do nothing and
  1690. **| complain not at all.  Cutting a row from a table only does something when
  1691. **| the row was actually a member, and otherwise does nothing silently.
  1692. **|
  1693. **|| row ref count: one can query the number of tables (and/or cells)
  1694. **| containing a row as a member or a child.
  1695. **|
  1696. **|| row content: one can access or modify the cell content in a table's row
  1697. **| by moving content to or from an instance of nsIMdbRow.  Note that nsIMdbRow
  1698. **| never represents the actual row inside a table, and this is the reason
  1699. **| why nsIMdbRow instances do not have row IDs or row scopes.  So an instance
  1700. **| of nsIMdbRow always and only contains a snapshot of some or all content in
  1701. **| past, present, or future persistent row inside a table.  This means that
  1702. **| reading and writing rows in tables has strictly copy semantics, and we
  1703. **| currently do not plan any exceptions for specific performance reasons.
  1704. **|
  1705. **|| sorting: note all rows are assumed sorted by row ID as a secondary
  1706. **| sort following the primary column sort, when table rows are sorted.
  1707. **|
  1708. **|| indexes:
  1709. |*/
  1710.  
  1711.  
  1712. #define NS_IMDBTABLE_IID_STR = "fe11bc98-d02b-4128-9fac-87042fdf9639"
  1713.  
  1714. #define NS_IMDBTABLE_IID \
  1715. {0xfe11bc98, 0xd02b, 0x4128, \
  1716. {0x9f, 0xac, 0x87, 0x04, 0x2f, 0xdf, 0x96, 0x39}}
  1717.  
  1718.  
  1719. class nsIMdbTable : public nsIMdbCollection { // a collection of rows
  1720. public:
  1721.  
  1722.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBTABLE_IID)
  1723. // { ===== begin nsIMdbTable methods =====
  1724.  
  1725.   // { ----- begin meta attribute methods -----
  1726.   NS_IMETHOD SetTablePriority(nsIMdbEnv* ev, mdb_priority inPrio) = 0;
  1727.   NS_IMETHOD GetTablePriority(nsIMdbEnv* ev, mdb_priority* outPrio) = 0;
  1728.   
  1729.   NS_IMETHOD GetTableBeVerbose(nsIMdbEnv* ev, mdb_bool* outBeVerbose) = 0;
  1730.   NS_IMETHOD SetTableBeVerbose(nsIMdbEnv* ev, mdb_bool inBeVerbose) = 0;
  1731.   
  1732.   NS_IMETHOD GetTableIsUnique(nsIMdbEnv* ev, mdb_bool* outIsUnique) = 0;
  1733.   
  1734.   NS_IMETHOD GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind) = 0;
  1735.   NS_IMETHOD GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope) = 0;
  1736.   
  1737.   NS_IMETHOD GetMetaRow(
  1738.     nsIMdbEnv* ev, // context
  1739.     const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying 
  1740.     mdbOid* outOid, // output meta row oid, can be nil to suppress output
  1741.     nsIMdbRow** acqRow) = 0; // acquire table's unique singleton meta row
  1742.     // The purpose of a meta row is to support the persistent recording of
  1743.     // meta info about a table as cells put into the distinguished meta row.
  1744.     // Each table has exactly one meta row, which is not considered a member
  1745.     // of the collection of rows inside the table.  The only way to tell
  1746.     // whether a row is a meta row is by the fact that it is returned by this
  1747.     // GetMetaRow() method from some table. Otherwise nothing distinguishes
  1748.     // a meta row from any other row.  A meta row can be used anyplace that
  1749.     // any other row can be used, and can even be put into other tables (or
  1750.     // the same table) as a table member, if this is useful for some reason.
  1751.     // The first attempt to access a table's meta row using GetMetaRow() will
  1752.     // cause the meta row to be created if it did not already exist.  When the
  1753.     // meta row is created, it will have the row oid that was previously
  1754.     // requested for this table's meta row; or if no oid was ever explicitly
  1755.     // specified for this meta row, then a unique oid will be generated in
  1756.     // the row scope named "m" (so obviously MDB clients should not
  1757.     // manually allocate any row IDs from that special meta scope namespace).
  1758.     // The meta row oid can be specified either when the table is created, or
  1759.     // else the first time that GetMetaRow() is called, by passing a non-nil
  1760.     // pointer to an oid for parameter inOptionalMetaRowOid.  The meta row's
  1761.     // actual oid is returned in outOid (if this is a non-nil pointer), and
  1762.     // it will be different from inOptionalMetaRowOid when the meta row was
  1763.     // already given a different oid earlier.
  1764.   // } ----- end meta attribute methods -----
  1765.  
  1766.  
  1767.   // { ----- begin cursor methods -----
  1768.   NS_IMETHOD GetTableRowCursor( // make a cursor, starting iteration at inRowPos
  1769.     nsIMdbEnv* ev, // context
  1770.     mdb_pos inRowPos, // zero-based ordinal position of row in table
  1771.     nsIMdbTableRowCursor** acqCursor) = 0; // acquire new cursor instance
  1772.   // } ----- end row position methods -----
  1773.  
  1774.   // { ----- begin row position methods -----
  1775.   NS_IMETHOD PosToOid( // get row member for a table position
  1776.     nsIMdbEnv* ev, // context
  1777.     mdb_pos inRowPos, // zero-based ordinal position of row in table
  1778.     mdbOid* outOid) = 0; // row oid at the specified position
  1779.  
  1780.   NS_IMETHOD OidToPos( // test for the table position of a row member
  1781.     nsIMdbEnv* ev, // context
  1782.     const mdbOid* inOid, // row to find in table
  1783.     mdb_pos* outPos) = 0; // zero-based ordinal position of row in table
  1784.     
  1785.   NS_IMETHOD PosToRow( // test for the table position of a row member
  1786.     nsIMdbEnv* ev, // context
  1787.     mdb_pos inRowPos, // zero-based ordinal position of row in table
  1788.     nsIMdbRow** acqRow) = 0; // acquire row at table position inRowPos
  1789.     
  1790.   NS_IMETHOD RowToPos( // test for the table position of a row member
  1791.     nsIMdbEnv* ev, // context
  1792.     nsIMdbRow* ioRow, // row to find in table
  1793.     mdb_pos* outPos) = 0; // zero-based ordinal position of row in table
  1794.   // } ----- end row position methods -----
  1795.  
  1796.   // { ----- begin oid set methods -----
  1797.   NS_IMETHOD AddOid( // make sure the row with inOid is a table member 
  1798.     nsIMdbEnv* ev, // context
  1799.     const mdbOid* inOid) = 0; // row to ensure membership in table
  1800.  
  1801.   NS_IMETHOD HasOid( // test for the table position of a row member
  1802.     nsIMdbEnv* ev, // context
  1803.     const mdbOid* inOid, // row to find in table
  1804.     mdb_bool* outHasOid) = 0; // whether inOid is a member row
  1805.  
  1806.   NS_IMETHOD CutOid( // make sure the row with inOid is not a member 
  1807.     nsIMdbEnv* ev, // context
  1808.     const mdbOid* inOid) = 0; // row to remove from table
  1809.   // } ----- end oid set methods -----
  1810.  
  1811.   // { ----- begin row set methods -----
  1812.   NS_IMETHOD NewRow( // create a new row instance in table
  1813.     nsIMdbEnv* ev, // context
  1814.     mdbOid* ioOid, // please use minus one (unbound) rowId for db-assigned IDs
  1815.     nsIMdbRow** acqRow) = 0; // create new row
  1816.  
  1817.   NS_IMETHOD AddRow( // make sure the row with inOid is a table member 
  1818.     nsIMdbEnv* ev, // context
  1819.     nsIMdbRow* ioRow) = 0; // row to ensure membership in table
  1820.  
  1821.   NS_IMETHOD HasRow( // test for the table position of a row member
  1822.     nsIMdbEnv* ev, // context
  1823.     nsIMdbRow* ioRow, // row to find in table
  1824.     mdb_bool* outHasRow) = 0; // whether row is a table member
  1825.  
  1826.   NS_IMETHOD CutRow( // make sure the row with inOid is not a member 
  1827.     nsIMdbEnv* ev, // context
  1828.     nsIMdbRow* ioRow) = 0; // row to remove from table
  1829.  
  1830.   NS_IMETHOD CutAllRows( // remove all rows from the table
  1831.     nsIMdbEnv* ev) = 0; // context
  1832.   // } ----- end row set methods -----
  1833.  
  1834.   // { ----- begin hinting methods -----
  1835.   NS_IMETHOD SearchColumnsHint( // advise re future expected search cols  
  1836.     nsIMdbEnv* ev, // context
  1837.     const mdbColumnSet* inColumnSet) = 0; // columns likely to be searched
  1838.     
  1839.   NS_IMETHOD SortColumnsHint( // advise re future expected sort columns  
  1840.     nsIMdbEnv* ev, // context
  1841.     const mdbColumnSet* inColumnSet) = 0; // columns for likely sort requests
  1842.     
  1843.   NS_IMETHOD StartBatchChangeHint( // advise before many adds and cuts  
  1844.     nsIMdbEnv* ev, // context
  1845.     const void* inLabel) = 0; // intend unique address to match end call
  1846.     // If batch starts nest by virtue of nesting calls in the stack, then
  1847.     // the address of a local variable makes a good batch start label that
  1848.     // can be used at batch end time, and such addresses remain unique.
  1849.     
  1850.   NS_IMETHOD EndBatchChangeHint( // advise before many adds and cuts  
  1851.     nsIMdbEnv* ev, // context
  1852.     const void* inLabel) = 0; // label matching start label
  1853.     // Suppose a table is maintaining one or many sort orders for a table,
  1854.     // so that every row added to the table must be inserted in each sort,
  1855.     // and every row cut must be removed from each sort.  If a db client
  1856.     // intends to make many such changes before needing any information
  1857.     // about the order or positions of rows inside a table, then a client
  1858.     // might tell the table to start batch changes in order to disable
  1859.     // sorting of rows for the interim.  Presumably a table will then do
  1860.     // a full sort of all rows at need when the batch changes end, or when
  1861.     // a surprise request occurs for row position during batch changes.
  1862.   // } ----- end hinting methods -----
  1863.  
  1864.   // { ----- begin searching methods -----
  1865.   NS_IMETHOD FindRowMatches( // search variable number of sorted cols
  1866.     nsIMdbEnv* ev, // context
  1867.     const mdbYarn* inPrefix, // content to find as prefix in row's column cell
  1868.     nsIMdbTableRowCursor** acqCursor) = 0; // set of matching rows
  1869.     
  1870.   NS_IMETHOD GetSearchColumns( // query columns used by FindRowMatches()
  1871.     nsIMdbEnv* ev, // context
  1872.     mdb_count* outCount, // context
  1873.     mdbColumnSet* outColSet) = 0; // caller supplied space to put columns
  1874.     // GetSearchColumns() returns the columns actually searched when the
  1875.     // FindRowMatches() method is called.  No more than mColumnSet_Count
  1876.     // slots of mColumnSet_Columns will be written, since mColumnSet_Count
  1877.     // indicates how many slots are present in the column array.  The
  1878.     // actual number of search column used by the table is returned in
  1879.     // the outCount parameter; if this number exceeds mColumnSet_Count,
  1880.     // then a caller needs a bigger array to read the entire column set.
  1881.     // The minimum of mColumnSet_Count and outCount is the number slots
  1882.     // in mColumnSet_Columns that were actually written by this method.
  1883.     //
  1884.     // Callers are expected to change this set of columns by calls to
  1885.     // nsIMdbTable::SearchColumnsHint() or SetSearchSorting(), or both.
  1886.   // } ----- end searching methods -----
  1887.  
  1888.   // { ----- begin sorting methods -----
  1889.   // sorting: note all rows are assumed sorted by row ID as a secondary
  1890.   // sort following the primary column sort, when table rows are sorted.
  1891.  
  1892.   NS_IMETHOD
  1893.   CanSortColumn( // query which column is currently used for sorting
  1894.     nsIMdbEnv* ev, // context
  1895.     mdb_column inColumn, // column to query sorting potential
  1896.     mdb_bool* outCanSort) = 0; // whether the column can be sorted
  1897.     
  1898.   NS_IMETHOD GetSorting( // view same table in particular sorting
  1899.     nsIMdbEnv* ev, // context
  1900.     mdb_column inColumn, // requested new column for sorting table
  1901.     nsIMdbSorting** acqSorting) = 0; // acquire sorting for column
  1902.     
  1903.   NS_IMETHOD SetSearchSorting( // use this sorting in FindRowMatches()
  1904.     nsIMdbEnv* ev, // context
  1905.     mdb_column inColumn, // often same as nsIMdbSorting::GetSortColumn()
  1906.     nsIMdbSorting* ioSorting) = 0; // requested sorting for some column
  1907.     // SetSearchSorting() attempts to inform the table that ioSorting
  1908.     // should be used during calls to FindRowMatches() for searching
  1909.     // the column which is actually sorted by ioSorting.  This method
  1910.     // is most useful in conjunction with nsIMdbSorting::SetCompare(),
  1911.     // because otherwise a caller would not be able to override the
  1912.     // comparison ordering method used during searchs.  Note that some
  1913.     // database implementations might be unable to use an arbitrarily
  1914.     // specified sort order, either due to schema or runtime interface
  1915.     // constraints, in which case ioSorting might not actually be used.
  1916.     // Presumably ioSorting is an instance that was returned from some
  1917.     // earlier call to nsIMdbTable::GetSorting().  A caller can also
  1918.     // use nsIMdbTable::SearchColumnsHint() to specify desired change
  1919.     // in which columns are sorted and searched by FindRowMatches().
  1920.     //
  1921.     // A caller can pass a nil pointer for ioSorting to request that
  1922.     // column inColumn no longer be used at all by FindRowMatches().
  1923.     // But when ioSorting is non-nil, then inColumn should match the
  1924.     // column actually sorted by ioSorting; when these do not agree,
  1925.     // implementations are instructed to give precedence to the column
  1926.     // specified by ioSorting (so this means callers might just pass
  1927.     // zero for inColumn when ioSorting is also provided, since then
  1928.     // inColumn is both redundant and ignored).
  1929.   // } ----- end sorting methods -----
  1930.  
  1931.   // { ----- begin moving methods -----
  1932.   // moving a row does nothing unless a table is currently unsorted
  1933.   
  1934.   NS_IMETHOD MoveOid( // change position of row in unsorted table
  1935.     nsIMdbEnv* ev, // context
  1936.     const mdbOid* inOid,  // row oid to find in table
  1937.     mdb_pos inHintFromPos, // suggested hint regarding start position
  1938.     mdb_pos inToPos,       // desired new position for row inRowId
  1939.     mdb_pos* outActualPos) = 0; // actual new position of row in table
  1940.  
  1941.   NS_IMETHOD MoveRow( // change position of row in unsorted table
  1942.     nsIMdbEnv* ev, // context
  1943.     nsIMdbRow* ioRow,  // row oid to find in table
  1944.     mdb_pos inHintFromPos, // suggested hint regarding start position
  1945.     mdb_pos inToPos,       // desired new position for row inRowId
  1946.     mdb_pos* outActualPos) = 0; // actual new position of row in table
  1947.   // } ----- end moving methods -----
  1948.   
  1949.   // { ----- begin index methods -----
  1950.   NS_IMETHOD AddIndex( // create a sorting index for column if possible
  1951.     nsIMdbEnv* ev, // context
  1952.     mdb_column inColumn, // the column to sort by index
  1953.     nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental index building
  1954.   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  1955.   // then the index addition will be finished.
  1956.   
  1957.   NS_IMETHOD CutIndex( // stop supporting a specific column index
  1958.     nsIMdbEnv* ev, // context
  1959.     mdb_column inColumn, // the column with index to be removed
  1960.     nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental index destroy
  1961.   // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
  1962.   // then the index removal will be finished.
  1963.   
  1964.   NS_IMETHOD HasIndex( // query for current presence of a column index
  1965.     nsIMdbEnv* ev, // context
  1966.     mdb_column inColumn, // the column to investigate
  1967.     mdb_bool* outHasIndex) = 0; // whether column has index for this column
  1968.  
  1969.   
  1970.   NS_IMETHOD EnableIndexOnSort( // create an index for col on first sort
  1971.     nsIMdbEnv* ev, // context
  1972.     mdb_column inColumn) = 0; // the column to index if ever sorted
  1973.   
  1974.   NS_IMETHOD QueryIndexOnSort( // check whether index on sort is enabled
  1975.     nsIMdbEnv* ev, // context
  1976.     mdb_column inColumn, // the column to investigate
  1977.     mdb_bool* outIndexOnSort) = 0; // whether column has index-on-sort enabled
  1978.   
  1979.   NS_IMETHOD DisableIndexOnSort( // prevent future index creation on sort
  1980.     nsIMdbEnv* ev, // context
  1981.     mdb_column inColumn) = 0; // the column to index if ever sorted
  1982.   // } ----- end index methods -----
  1983.  
  1984. // } ===== end nsIMdbTable methods =====
  1985. };
  1986.  
  1987. /*| nsIMdbSorting: a view of a table in some particular sort order.  This
  1988. **| row order closely resembles a readonly array of rows with the same row
  1989. **| membership as the underlying table, but in a different order than the
  1990. **| table's explicit row order.  But the sorting's row membership changes
  1991. **| whenever the table's membership changes (without any notification, so
  1992. **| keep this in mind when modifying the table).
  1993. **|
  1994. **|| table: every sorting is associated with a particular table.  You
  1995. **| cannot change which table is used by a sorting (just ask some new
  1996. **| table for a suitable sorting instance instead).
  1997. **|
  1998. **|| compare: the ordering method used by a sorting, wrapped up in a
  1999. **| abstract plug-in interface.  When this was never installed by an
  2000. **| explicit call to SetNewCompare(), a compare object is still returned,
  2001. **| and it might match the compare instance returned by the factory method
  2002. **| nsIMdbFactory::MakeCompare(), which represents a default sort order
  2003. **| (which we fervently hope is consistently ASCII byte ordering).
  2004. **|
  2005. **|| cursor: in case callers are more comfortable with a cursor style
  2006. **| of accessing row members, each sorting will happily return a cursor
  2007. **| instance with behavior very similar to a cursor returned from a call
  2008. **| to nsIMdbTable::GetTableRowCursor(), but with different row order.
  2009. **| A cursor should show exactly the same information as the pos methods.
  2010. **|
  2011. **|| pos: the PosToOid() and PosToRow() methods are just like the table
  2012. **| methods of the same name, except they show rows in the sort order of 
  2013. **| the sorting, rather than that of the table.  These methods are like
  2014. **| readonly array position accessor's, or like a C++ operator[].
  2015. |*/
  2016. class nsIMdbSorting : public nsIMdbObject { // sorting of some table
  2017. public:
  2018. // { ===== begin nsIMdbSorting methods =====
  2019.  
  2020.   // { ----- begin attribute methods -----
  2021.   // sorting: note all rows are assumed sorted by row ID as a secondary
  2022.   // sort following the primary column sort, when table rows are sorted.
  2023.   
  2024.   NS_IMETHOD GetTable(nsIMdbEnv* ev, nsIMdbTable** acqTable) = 0;
  2025.   NS_IMETHOD GetSortColumn( // query which col is currently sorted
  2026.     nsIMdbEnv* ev, // context
  2027.     mdb_column* outColumn) = 0; // col the table uses for sorting (or zero)
  2028.  
  2029.   NS_IMETHOD SetNewCompare(nsIMdbEnv* ev,
  2030.     nsIMdbCompare* ioNewCompare) = 0;
  2031.     // Setting the sorting's compare object will typically cause the rows
  2032.     // to be resorted, presumably in a lazy fashion when the sorting is
  2033.     // next required to be in a valid row ordering state, such as when a
  2034.     // call to PosToOid() happens.  ioNewCompare can be nil, in which case
  2035.     // implementations should revert to the default sort order, which must
  2036.     // be equivalent to whatever is used by nsIMdbFactory::MakeCompare().
  2037.  
  2038.   NS_IMETHOD GetOldCompare(nsIMdbEnv* ev,
  2039.     nsIMdbCompare** acqOldCompare) = 0;
  2040.     // Get this sorting instance's compare object, which handles the
  2041.     // ordering of rows in the sorting, by comparing yarns from the cells
  2042.     // in the column being sorted.  Since nsIMdbCompare has no interface
  2043.     // to query the state of the compare object, it is not clear what you
  2044.     // would do with this object when returned, except maybe compare it
  2045.     // as a pointer address to some other instance, to check identities.
  2046.   
  2047.   // } ----- end attribute methods -----
  2048.  
  2049.   // { ----- begin cursor methods -----
  2050.   NS_IMETHOD GetSortingRowCursor( // make a cursor, starting at inRowPos
  2051.     nsIMdbEnv* ev, // context
  2052.     mdb_pos inRowPos, // zero-based ordinal position of row in table
  2053.     nsIMdbTableRowCursor** acqCursor) = 0; // acquire new cursor instance
  2054.     // A cursor interface turning same info as PosToOid() or PosToRow().
  2055.   // } ----- end row position methods -----
  2056.  
  2057.   // { ----- begin row position methods -----
  2058.   NS_IMETHOD PosToOid( // get row member for a table position
  2059.     nsIMdbEnv* ev, // context
  2060.     mdb_pos inRowPos, // zero-based ordinal position of row in table
  2061.     mdbOid* outOid) = 0; // row oid at the specified position
  2062.     
  2063.   NS_IMETHOD PosToRow( // test for the table position of a row member
  2064.     nsIMdbEnv* ev, // context
  2065.     mdb_pos inRowPos, // zero-based ordinal position of row in table
  2066.     nsIMdbRow** acqRow) = 0; // acquire row at table position inRowPos
  2067.   // } ----- end row position methods -----
  2068.  
  2069. // } ===== end nsIMdbSorting methods =====
  2070. };
  2071.  
  2072. /*| nsIMdbTableRowCursor: cursor class for iterating table rows
  2073. **|
  2074. **|| table: the cursor is associated with a specific table, which can be
  2075. **| set to a different table (which resets the position to -1 so the
  2076. **| next row acquired is the first in the table.
  2077. **|
  2078. **|| NextRowId: the rows in the table can be iterated by identity alone,
  2079. **| without actually reading the cells of any row with this method.
  2080. **|
  2081. **|| NextRowCells: read the next row in the table, but only read cells
  2082. **| from the table which are already present in the row (so no new cells
  2083. **| are added to the row, even if they are present in the table).  All the
  2084. **| cells will have content specified, even it is the empty string.  No
  2085. **| columns will be removed, even if missing from the row (because missing
  2086. **| and empty are semantically equivalent).
  2087. **|
  2088. **|| NextRowAllCells: read the next row in the table, and access all the
  2089. **| cells for this row in the table, adding any missing columns to the row
  2090. **| as needed until all cells are represented.  All the
  2091. **| cells will have content specified, even it is the empty string.  No
  2092. **| columns will be removed, even if missing from the row (because missing
  2093. **| and empty are semantically equivalent).
  2094. **|
  2095. |*/
  2096.  
  2097. #define NS_IMDBTABLEROWCURSOR_IID_STR = "4f325dad-0385-4b62-a992-c914ab93587e"
  2098.  
  2099. #define NS_IMDBTABLEROWCURSOR_IID \
  2100. {0x4f325dad, 0x0385, 0x4b62, \
  2101. {0xa9, 0x92, 0xc9, 0x14, 0xab, 0x93, 0x58, 0x7e}}
  2102.  
  2103.  
  2104.  
  2105. class nsIMdbTableRowCursor : public nsISupports { // table row iterator
  2106. public:
  2107.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBTABLEROWCURSOR_IID)
  2108.  
  2109. // { ===== begin nsIMdbTableRowCursor methods =====
  2110.  
  2111.   // { ----- begin attribute methods -----
  2112.   // NS_IMETHOD SetTable(nsIMdbEnv* ev, nsIMdbTable* ioTable) = 0; // sets pos to -1
  2113.   // Method SetTable() cut and made obsolete in keeping with new sorting methods.
  2114.   
  2115.   NS_IMETHOD GetTable(nsIMdbEnv* ev, nsIMdbTable** acqTable) = 0;
  2116.   // } ----- end attribute methods -----
  2117.  
  2118.   // { ----- begin duplicate row removal methods -----
  2119.   NS_IMETHOD CanHaveDupRowMembers(nsIMdbEnv* ev, // cursor might hold dups?
  2120.     mdb_bool* outCanHaveDups) = 0;
  2121.     
  2122.   NS_IMETHOD MakeUniqueCursor( // clone cursor, removing duplicate rows
  2123.     nsIMdbEnv* ev, // context
  2124.     nsIMdbTableRowCursor** acqCursor) = 0;    // acquire clone with no dups
  2125.     // Note that MakeUniqueCursor() is never necessary for a cursor which was
  2126.     // created by table method nsIMdbTable::GetTableRowCursor(), because a table
  2127.     // never contains the same row as a member more than once.  However, a cursor
  2128.     // created by table method nsIMdbTable::FindRowMatches() might contain the
  2129.     // same row more than once, because the same row can generate a hit by more
  2130.     // than one column with a matching string prefix.  Note this method can
  2131.     // return the very same cursor instance with just an incremented refcount,
  2132.     // when the original cursor could not contain any duplicate rows (calling
  2133.     // CanHaveDupRowMembers() shows this case on a false return).  Otherwise
  2134.     // this method returns a different cursor instance.  Callers should not use
  2135.     // this MakeUniqueCursor() method lightly, because it tends to defeat the
  2136.     // purpose of lazy programming techniques, since it can force creation of
  2137.     // an explicit row collection in a new cursor's representation, in order to
  2138.     // inspect the row membership and remove any duplicates; this can have big
  2139.     // impact if a collection holds tens of thousands of rows or more, when
  2140.     // the original cursor with dups simply referenced rows indirectly by row
  2141.     // position ranges, without using an explicit row set representation.
  2142.     // Callers are encouraged to use nsIMdbCursor::GetCount() to determine
  2143.     // whether the row collection is very large (tens of thousands), and to
  2144.     // delay calling MakeUniqueCursor() when possible, until a user interface
  2145.     // element actually demands the creation of an explicit set representation.
  2146.   // } ----- end duplicate row removal methods -----
  2147.  
  2148.   // { ----- begin oid iteration methods -----
  2149.   NS_IMETHOD NextRowOid( // get row id of next row in the table
  2150.     nsIMdbEnv* ev, // context
  2151.     mdbOid* outOid, // out row oid
  2152.     mdb_pos* outRowPos) = 0;    // zero-based position of the row in table
  2153.   // } ----- end oid iteration methods -----
  2154.  
  2155.   // { ----- begin row iteration methods -----
  2156.   NS_IMETHOD NextRow( // get row cells from table for cells already in row
  2157.     nsIMdbEnv* ev, // context
  2158.     nsIMdbRow** acqRow, // acquire next row in table
  2159.     mdb_pos* outRowPos) = 0;    // zero-based position of the row in table
  2160.  
  2161.   NS_IMETHOD PrevRowOid( // get row id of previous row in the table
  2162.     nsIMdbEnv* ev, // context
  2163.     mdbOid* outOid, // out row oid
  2164.     mdb_pos* outRowPos) = 0;    // zero-based position of the row in table
  2165.   // } ----- end oid iteration methods -----
  2166.  
  2167.   // { ----- begin row iteration methods -----
  2168.   NS_IMETHOD PrevRow( // get row cells from table for cells already in row
  2169.     nsIMdbEnv* ev, // context
  2170.     nsIMdbRow** acqRow, // acquire previous row in table
  2171.     mdb_pos* outRowPos) = 0;    // zero-based position of the row in table
  2172.  
  2173.   // } ----- end row iteration methods -----
  2174.  
  2175.   // { ----- begin copy iteration methods -----
  2176.   // NS_IMETHOD NextRowCopy( // put row cells into sink only when already in sink
  2177.   //   nsIMdbEnv* ev, // context
  2178.   //   nsIMdbRow* ioSinkRow, // sink for row cells read from next row
  2179.   //   mdbOid* outOid, // out row oid
  2180.   //   mdb_pos* outRowPos) = 0;    // zero-based position of the row in table
  2181.   // 
  2182.   // NS_IMETHOD NextRowCopyAll( // put all row cells into sink, adding to sink
  2183.   //   nsIMdbEnv* ev, // context
  2184.   //   nsIMdbRow* ioSinkRow, // sink for row cells read from next row
  2185.   //   mdbOid* outOid, // out row oid
  2186.   //   mdb_pos* outRowPos) = 0;    // zero-based position of the row in table
  2187.   // } ----- end copy iteration methods -----
  2188.  
  2189. // } ===== end nsIMdbTableRowCursor methods =====
  2190. };
  2191.  
  2192. /*| nsIMdbRow: a collection of cells
  2193. **|
  2194. |*/
  2195.  
  2196. #define NS_IMDBROW_IID_STR "271e8d6e-183a-40e3-9f18-36913b4c7853"
  2197.  
  2198.  
  2199. #define NS_IMDBROW_IID \
  2200. {0x271e8d6e, 0x183a, 0x40e3, \
  2201. {0x9f, 0x18, 0x36, 0x91, 0x3b, 0x4c, 0x78, 0x53}}
  2202.  
  2203.  
  2204. class nsIMdbRow : public nsIMdbCollection { // cell tuple
  2205. public:
  2206.  
  2207.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBROW_IID)
  2208. // { ===== begin nsIMdbRow methods =====
  2209.  
  2210.   // { ----- begin cursor methods -----
  2211.   NS_IMETHOD GetRowCellCursor( // make a cursor starting iteration at inCellPos
  2212.     nsIMdbEnv* ev, // context
  2213.     mdb_pos inCellPos, // zero-based ordinal position of cell in row
  2214.     nsIMdbRowCellCursor** acqCursor) = 0; // acquire new cursor instance
  2215.   // } ----- end cursor methods -----
  2216.  
  2217.   // { ----- begin column methods -----
  2218.   NS_IMETHOD AddColumn( // make sure a particular column is inside row
  2219.     nsIMdbEnv* ev, // context
  2220.     mdb_column inColumn, // column to add
  2221.     const mdbYarn* inYarn) = 0; // cell value to install
  2222.  
  2223.   NS_IMETHOD CutColumn( // make sure a column is absent from the row
  2224.     nsIMdbEnv* ev, // context
  2225.     mdb_column inColumn) = 0; // column to ensure absent from row
  2226.  
  2227.   NS_IMETHOD CutAllColumns( // remove all columns from the row
  2228.     nsIMdbEnv* ev) = 0; // context
  2229.   // } ----- end column methods -----
  2230.  
  2231.   // { ----- begin cell methods -----
  2232.   NS_IMETHOD NewCell( // get cell for specified column, or add new one
  2233.     nsIMdbEnv* ev, // context
  2234.     mdb_column inColumn, // column to add
  2235.     nsIMdbCell** acqCell) = 0; // cell column and value
  2236.     
  2237.   NS_IMETHOD AddCell( // copy a cell from another row to this row
  2238.     nsIMdbEnv* ev, // context
  2239.     const nsIMdbCell* inCell) = 0; // cell column and value
  2240.     
  2241.   NS_IMETHOD GetCell( // find a cell in this row
  2242.     nsIMdbEnv* ev, // context
  2243.     mdb_column inColumn, // column to find
  2244.     nsIMdbCell** acqCell) = 0; // cell for specified column, or null
  2245.     
  2246.   NS_IMETHOD EmptyAllCells( // make all cells in row empty of content
  2247.     nsIMdbEnv* ev) = 0; // context
  2248.   // } ----- end cell methods -----
  2249.  
  2250.   // { ----- begin row methods -----
  2251.   NS_IMETHOD AddRow( // add all cells in another row to this one
  2252.     nsIMdbEnv* ev, // context
  2253.     nsIMdbRow* ioSourceRow) = 0; // row to union with
  2254.     
  2255.   NS_IMETHOD SetRow( // make exact duplicate of another row
  2256.     nsIMdbEnv* ev, // context
  2257.     nsIMdbRow* ioSourceRow) = 0; // row to duplicate
  2258.   // } ----- end row methods -----
  2259.  
  2260.   // { ----- begin blob methods -----  
  2261.   NS_IMETHOD SetCellYarn(nsIMdbEnv* ev, // synonym for AddColumn()
  2262.     mdb_column inColumn, // column to write
  2263.     const mdbYarn* inYarn) = 0;   // reads from yarn slots
  2264.   // make this text object contain content from the yarn's buffer
  2265.   
  2266.   NS_IMETHOD GetCellYarn(nsIMdbEnv* ev, 
  2267.     mdb_column inColumn, // column to read 
  2268.     mdbYarn* outYarn) = 0;  // writes some yarn slots 
  2269.   // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
  2270.   
  2271.   NS_IMETHOD AliasCellYarn(nsIMdbEnv* ev, 
  2272.     mdb_column inColumn, // column to alias
  2273.     mdbYarn* outYarn) = 0; // writes ALL yarn slots
  2274.   
  2275.   NS_IMETHOD NextCellYarn(nsIMdbEnv* ev, // iterative version of GetCellYarn()
  2276.     mdb_column* ioColumn, // next column to read
  2277.     mdbYarn* outYarn) = 0;  // writes some yarn slots 
  2278.   // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
  2279.   //
  2280.   // The ioColumn argument is an inout parameter which initially contains the
  2281.   // last column accessed and returns the next column corresponding to the
  2282.   // content read into the yarn.  Callers should start with a zero column
  2283.   // value to say 'no previous column', which causes the first column to be
  2284.   // read.  Then the value returned in ioColumn is perfect for the next call
  2285.   // to NextCellYarn(), since it will then be the previous column accessed.
  2286.   // Callers need only examine the column token returned to see which cell
  2287.   // in the row is being read into the yarn.  When no more columns remain,
  2288.   // and the iteration has ended, ioColumn will return a zero token again.
  2289.   // So iterating over cells starts and ends with a zero column token.
  2290.  
  2291.   NS_IMETHOD SeekCellYarn( // resembles nsIMdbRowCellCursor::SeekCell()
  2292.     nsIMdbEnv* ev, // context
  2293.     mdb_pos inPos, // position of cell in row sequence
  2294.     mdb_column* outColumn, // column for this particular cell
  2295.     mdbYarn* outYarn) = 0; // writes some yarn slots
  2296.   // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
  2297.   // Callers can pass nil for outYarn to indicate no interest in content, so
  2298.   // only the outColumn value is returned.  NOTE to subclasses: you must be
  2299.   // able to ignore outYarn when the pointer is nil; please do not crash.
  2300.  
  2301.   // } ----- end blob methods -----
  2302.  
  2303. // } ===== end nsIMdbRow methods =====
  2304. };
  2305.  
  2306. /*| nsIMdbRowCellCursor: cursor class for iterating row cells
  2307. **|
  2308. **|| row: the cursor is associated with a specific row, which can be
  2309. **| set to a different row (which resets the position to -1 so the
  2310. **| next cell acquired is the first in the row.
  2311. **|
  2312. **|| NextCell: get the next cell in the row and return its position and
  2313. **| a new instance of a nsIMdbCell to represent this next cell.
  2314. |*/
  2315.  
  2316. #define NS_IMDBROWCELLCURSOR_IID_STR "b33371a7-5d63-4d10-85a8-e44dffe75c28"
  2317.  
  2318.  
  2319. #define NS_IMDBROWCELLCURSOR_IID \
  2320. {0x271e8d6e, 0x5d63, 0x4d10 , \
  2321. {0x85, 0xa8, 0xe4, 0x4d, 0xff, 0xe7, 0x5c, 0x28}}
  2322.  
  2323.  
  2324. class nsIMdbRowCellCursor : public nsISupports{ // cell collection iterator
  2325. public:
  2326.  
  2327.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBROWCELLCURSOR_IID)
  2328. // { ===== begin nsIMdbRowCellCursor methods =====
  2329.  
  2330.   // { ----- begin attribute methods -----
  2331.   NS_IMETHOD SetRow(nsIMdbEnv* ev, nsIMdbRow* ioRow) = 0; // sets pos to -1
  2332.   NS_IMETHOD GetRow(nsIMdbEnv* ev, nsIMdbRow** acqRow) = 0;
  2333.   // } ----- end attribute methods -----
  2334.  
  2335.   // { ----- begin cell creation methods -----
  2336.   NS_IMETHOD MakeCell( // get cell at current pos in the row
  2337.     nsIMdbEnv* ev, // context
  2338.     mdb_column* outColumn, // column for this particular cell
  2339.     mdb_pos* outPos, // position of cell in row sequence
  2340.     nsIMdbCell** acqCell) = 0; // the cell at inPos
  2341.   // } ----- end cell creation methods -----
  2342.  
  2343.   // { ----- begin cell seeking methods -----
  2344.   NS_IMETHOD SeekCell( // same as SetRow() followed by MakeCell()
  2345.     nsIMdbEnv* ev, // context
  2346.     mdb_pos inPos, // position of cell in row sequence
  2347.     mdb_column* outColumn, // column for this particular cell
  2348.     nsIMdbCell** acqCell) = 0; // the cell at inPos
  2349.   // } ----- end cell seeking methods -----
  2350.  
  2351.   // { ----- begin cell iteration methods -----
  2352.   NS_IMETHOD NextCell( // get next cell in the row
  2353.     nsIMdbEnv* ev, // context
  2354.     nsIMdbCell** acqCell, // changes to the next cell in the iteration
  2355.     mdb_column* outColumn, // column for this particular cell
  2356.     mdb_pos* outPos) = 0; // position of cell in row sequence
  2357.     
  2358.   NS_IMETHOD PickNextCell( // get next cell in row within filter set
  2359.     nsIMdbEnv* ev, // context
  2360.     nsIMdbCell* ioCell, // changes to the next cell in the iteration
  2361.     const mdbColumnSet* inFilterSet, // col set of actual caller interest
  2362.     mdb_column* outColumn, // column for this particular cell
  2363.     mdb_pos* outPos) = 0; // position of cell in row sequence
  2364.  
  2365.   // Note that inFilterSet should not have too many (many more than 10?)
  2366.   // cols, since this might imply a potential excessive consumption of time
  2367.   // over many cursor calls when looking for column and filter intersection.
  2368.   // } ----- end cell iteration methods -----
  2369.  
  2370. // } ===== end nsIMdbRowCellCursor methods =====
  2371. };
  2372.  
  2373. /*| nsIMdbBlob: a base class for objects composed mainly of byte sequence state.
  2374. **| (This provides a base class for nsIMdbCell, so that cells themselves can
  2375. **| be used to set state in another cell, without extracting a buffer.)
  2376. |*/
  2377. class nsIMdbBlob : public nsISupports { // a string with associated charset
  2378. public:
  2379.  
  2380. // { ===== begin nsIMdbBlob methods =====
  2381.  
  2382.   // { ----- begin attribute methods -----
  2383.   NS_IMETHOD SetBlob(nsIMdbEnv* ev,
  2384.     nsIMdbBlob* ioBlob) = 0; // reads inBlob slots
  2385.   // when inBlob is in the same suite, this might be fastest cell-to-cell
  2386.   
  2387.   NS_IMETHOD ClearBlob( // make empty (so content has zero length)
  2388.     nsIMdbEnv* ev) = 0;
  2389.   // clearing a yarn is like SetYarn() with empty yarn instance content
  2390.   
  2391.   NS_IMETHOD GetBlobFill(nsIMdbEnv* ev,
  2392.     mdb_fill* outFill) = 0;  // size of blob 
  2393.   // Same value that would be put into mYarn_Fill, if one called GetYarn()
  2394.   // with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0.
  2395.   
  2396.   NS_IMETHOD SetYarn(nsIMdbEnv* ev, 
  2397.     const mdbYarn* inYarn) = 0;   // reads from yarn slots
  2398.   // make this text object contain content from the yarn's buffer
  2399.   
  2400.   NS_IMETHOD GetYarn(nsIMdbEnv* ev, 
  2401.     mdbYarn* outYarn) = 0;  // writes some yarn slots 
  2402.   // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
  2403.   
  2404.   NS_IMETHOD AliasYarn(nsIMdbEnv* ev, 
  2405.     mdbYarn* outYarn) = 0; // writes ALL yarn slots
  2406.   // AliasYarn() reveals sensitive internal text buffer state to the caller
  2407.   // by setting mYarn_Buf to point into the guts of this text implementation.
  2408.   //
  2409.   // The caller must take great care to avoid writing on this space, and to
  2410.   // avoid calling any method that would cause the state of this text object
  2411.   // to change (say by directly or indirectly setting the text to hold more
  2412.   // content that might grow the size of the buffer and free the old buffer).
  2413.   // In particular, callers should scrupulously avoid making calls into the
  2414.   // mdb interface to write any content while using the buffer pointer found
  2415.   // in the returned yarn instance.  Best safe usage involves copying content
  2416.   // into some other kind of external content representation beyond mdb.
  2417.   //
  2418.   // (The original design of this method a week earlier included the concept
  2419.   // of very fast and efficient cooperative locking via a pointer to some lock
  2420.   // member slot.  But let's ignore that complexity in the current design.)
  2421.   //
  2422.   // AliasYarn() is specifically intended as the first step in transferring
  2423.   // content from nsIMdbBlob to a nsString representation, without forcing extra
  2424.   // allocations and/or memory copies. (A standard nsIMdbBlob_AsString() utility
  2425.   // will use AliasYarn() as the first step in setting a nsString instance.)
  2426.   //
  2427.   // This is an alternative to the GetYarn() method, which has copy semantics
  2428.   // only; AliasYarn() relaxes a robust safety principle only for performance
  2429.   // reasons, to accomodate the need for callers to transform text content to
  2430.   // some other canonical representation that would necessitate an additional
  2431.   // copy and transformation when such is incompatible with the mdbYarn format.
  2432.   //
  2433.   // The implementation of AliasYarn() should have extremely little overhead
  2434.   // besides the virtual dispatch to the method implementation, and the code
  2435.   // necessary to populate all the mdbYarn member slots with internal buffer
  2436.   // address and metainformation that describes the buffer content.  Note that
  2437.   // mYarn_Grow must always be set to nil to indicate no resizing is allowed.
  2438.   
  2439.   // } ----- end attribute methods -----
  2440.  
  2441. // } ===== end nsIMdbBlob methods =====
  2442. };
  2443.  
  2444. /*| nsIMdbCell: the text in a single column of a row.  The base nsIMdbBlob
  2445. **| class provides all the interface related to accessing cell text.
  2446. **|
  2447. **|| column: each cell in a row appears in a specific column, where this
  2448. **| column is identified by the an integer mdb_scope value (generated by
  2449. **| the StringToScopeToken() method in the containing nsIMdbPort instance).
  2450. **| Because a row cannot have more than one cell with the same column,
  2451. **| something must give if one calls SetColumn() with an existing column
  2452. **| in the same row. When this happens, the other cell is replaced with
  2453. **| this cell (and the old cell is closed if it has outstanding refs).
  2454. **|
  2455. **|| row: every cell instance is a part of some row, and every cell knows
  2456. **| which row is the parent row.  (Note this should be represented by a
  2457. **| weak backpointer, so that outstanding cell references cannot keep a
  2458. **| row open that should be closed. Otherwise we'd have ref graph cycles.)
  2459. **|
  2460. **|| text: a cell can either be text, or it can have a child row or table,
  2461. **| but not both at once.  If text is read from a cell with a child, the text
  2462. **| content should be empty (for AliasYarn()) or a description of the type
  2463. **| of child (perhaps "mdb:cell:child:row" or "mdb:cell:child:table").
  2464. **|
  2465. **|| child: a cell might reference another row or a table, rather than text.
  2466. **| The interface for putting and getting children rows and tables was first
  2467. **| defined in the nsIMdbTable interface, but then this was moved to this cell
  2468. **| interface as more natural. 
  2469. |*/
  2470.  
  2471.  
  2472.  
  2473. #define NS_IMDBCELL_IID \
  2474. {0xa3b62f71, 0xa181, 0x4a91, \
  2475. {0xb6, 0x6b, 0x27, 0x10, 0x9b, 0x88, 0x98, 0x35}}
  2476.  
  2477. #define NS_IMDBCELL_IID_STR = "a3b62f71-a181-4a91-b66b-27109b889835"
  2478.  
  2479. class nsIMdbCell : public nsIMdbBlob { // text attribute in row with column scope
  2480. public:
  2481.  
  2482.   NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMDBTABLEROWCURSOR_IID)
  2483. // { ===== begin nsIMdbCell methods =====
  2484.  
  2485.   // { ----- begin attribute methods -----
  2486.   NS_IMETHOD SetColumn(nsIMdbEnv* ev, mdb_column inColumn) = 0; 
  2487.   NS_IMETHOD GetColumn(nsIMdbEnv* ev, mdb_column* outColumn) = 0;
  2488.   
  2489.   NS_IMETHOD GetCellInfo(  // all cell metainfo except actual content
  2490.     nsIMdbEnv* ev, 
  2491.     mdb_column* outColumn,           // the column in the containing row
  2492.     mdb_fill*   outBlobFill,         // the size of text content in bytes
  2493.     mdbOid*     outChildOid,         // oid of possible row or table child
  2494.     mdb_bool*   outIsRowChild) = 0;  // nonzero if child, and a row child
  2495.  
  2496.   // Checking all cell metainfo is a good way to avoid forcing a large cell
  2497.   // in to memory when you don't actually want to use the content.
  2498.   
  2499.   NS_IMETHOD GetRow(nsIMdbEnv* ev, // parent row for this cell
  2500.     nsIMdbRow** acqRow) = 0;
  2501.   NS_IMETHOD GetPort(nsIMdbEnv* ev, // port containing cell
  2502.     nsIMdbPort** acqPort) = 0;
  2503.   // } ----- end attribute methods -----
  2504.  
  2505.   // { ----- begin children methods -----
  2506.   NS_IMETHOD HasAnyChild( // does cell have a child instead of text?
  2507.     nsIMdbEnv* ev,
  2508.     mdbOid* outOid,  // out id of row or table (or unbound if no child)
  2509.     mdb_bool* outIsRow) = 0; // nonzero if child is a row (rather than a table)
  2510.  
  2511.   NS_IMETHOD GetAnyChild( // access table of specific attribute
  2512.     nsIMdbEnv* ev, // context
  2513.     nsIMdbRow** acqRow, // child row (or null)
  2514.     nsIMdbTable** acqTable) = 0; // child table (or null)
  2515.  
  2516.  
  2517.   NS_IMETHOD SetChildRow( // access table of specific attribute
  2518.     nsIMdbEnv* ev, // context
  2519.     nsIMdbRow* ioRow) = 0; // inRow must be bound inside this same db port
  2520.  
  2521.   NS_IMETHOD GetChildRow( // access row of specific attribute
  2522.     nsIMdbEnv* ev, // context
  2523.     nsIMdbRow** acqRow) = 0; // acquire child row (or nil if no child)
  2524.  
  2525.  
  2526.   NS_IMETHOD SetChildTable( // access table of specific attribute
  2527.     nsIMdbEnv* ev, // context
  2528.     nsIMdbTable* inTable) = 0; // table must be bound inside this same db port
  2529.  
  2530.   NS_IMETHOD GetChildTable( // access table of specific attribute
  2531.     nsIMdbEnv* ev, // context
  2532.     nsIMdbTable** acqTable) = 0; // acquire child table (or nil if no child)
  2533.   // } ----- end children methods -----
  2534.  
  2535. // } ===== end nsIMdbCell methods =====
  2536. };
  2537.  
  2538. // } %%%%% end C++ abstract class interfaces %%%%%
  2539.  
  2540. //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
  2541.  
  2542. #endif /* _MDB_ */
  2543.  
  2544.